Added Outlook mail and address book import functionality

This commit is contained in:
tonyr%fbdesigns.com 1999-11-01 00:46:18 +00:00
parent b19191c4a1
commit 48fdb40dd9
46 changed files with 9204 additions and 1 deletions

View File

@ -21,7 +21,7 @@ LocalDirs=public src resources
!if "$(_MSC_VER)" == "1200"
DIRS=$(LocalDirs) oexpress
DIRS=$(LocalDirs) oexpress outlook
!else
DIRS=$(LocalDirs)
!endif

View File

@ -0,0 +1,25 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
DIRS=resources src
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,28 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..\..\..
include <$(DEPTH)\config\rules.mak>
install::
$(MAKE_INSTALL) outlookImportMsgs.properties $(DIST)\bin\chrome\messenger\locale\en-US
clobber::
rm -f $(DIST)bin\chrome\messenger\locale\en-US\outlookImportMsgs.properties

View File

@ -0,0 +1,51 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
#
# The following are used by the outlook express import code to display status/error
# and informational messages
#
# Short name of import module
## @name OUTLOOKIMPORT_NAME
## @loc None
2000=Outlook
# Description of import module
## @name OUTLOOKIMPORT_DESCRIPTION
## @loc None
2001=Outlook mail and address books
# Success message
## @name OUTLOOKIMPORT_MAILBOX_SUCCESS
## @loc None
2002=Mailbox %S, imported %d messages
# Error message
## @name OUTLOOKIMPORT_MAILBOX_BADPARAM
## @loc None
2003=Bad parameter passed to import mailbox.
# Error message
## @name OUTLOOKIMPORT_MAILBOX_CONVERTERROR
## @loc None
2004=Error importing mailbox %S, all messages may not be imported from this mailbox.

View File

@ -0,0 +1,22 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..\..
DIRS= en-US
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,22 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..
DIRS= locale
include <$(DEPTH)\config\rules.mak>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,234 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef MapiApi_h___
#define MapiApi_h___
#include "nscore.h"
#include "nsString.h"
#include "nsVoidArray.h"
#include <stdio.h>
#include <windows.h>
#include <mapi.h>
#include <mapix.h>
#include <mapidefs.h>
#include <mapicode.h>
#include <mapitags.h>
#include <mapiutil.h>
// wabutil.h expects mapiutil to define _MAPIUTIL_H but it actually
// defines _MAPIUTIL_H_
#define _MAPIUTIL_H
class CMapiFolder {
public:
CMapiFolder();
CMapiFolder( const CMapiFolder *pCopyFrom);
CMapiFolder( const char *pDisplayName, ULONG cbEid, LPENTRYID lpEid, int depth, LONG oType = MAPI_FOLDER);
~CMapiFolder();
void SetDoImport( BOOL doIt) { m_doImport = doIt;}
void SetObjectType( long oType) { m_objectType = oType;}
void SetDisplayName( const char *pDisplayName) { m_displayName = pDisplayName;}
void SetEntryID( ULONG cbEid, LPENTRYID lpEid);
void SetDepth( int depth) { m_depth = depth;}
void SetFilePath( const char *pFilePath) { m_mailFilePath = pFilePath;}
BOOL GetDoImport( void) const { return( m_doImport);}
LONG GetObjectType( void) const { return( m_objectType);}
void GetDisplayName( nsCString& name) const { name = m_displayName;}
void GetFilePath( nsCString& path) const { path = m_mailFilePath;}
BOOL IsStore( void) const { return( m_objectType == MAPI_STORE);}
BOOL IsFolder( void) const { return( m_objectType == MAPI_FOLDER);}
int GetDepth( void) const { return( m_depth);}
LPENTRYID GetEntryID( ULONG *pCb = NULL) const { if (pCb) *pCb = m_cbEid; return( (LPENTRYID) m_lpEid);}
ULONG GetCBEntryID( void) const { return( m_cbEid);}
private:
LONG m_objectType;
ULONG m_cbEid;
BYTE * m_lpEid;
nsCString m_displayName;
int m_depth;
nsCString m_mailFilePath;
BOOL m_doImport;
};
class CMapiFolderList {
public:
CMapiFolderList();
~CMapiFolderList();
void AddItem( CMapiFolder *pFolder);
CMapiFolder * GetItem( int index) { if ((index >= 0) && (index < m_array.Count())) return( (CMapiFolder *)GetAt( index)); else return( NULL);}
void ClearAll( void);
// Debugging and reporting
void DumpList( void);
void * GetAt( int index) { return( m_array.ElementAt( index));}
int GetSize( void) { return( m_array.Count());}
protected:
void EnsureUniqueName( CMapiFolder *pFolder);
void GenerateFilePath( CMapiFolder *pFolder);
void ChangeName( nsCString& name);
private:
nsVoidArray m_array;
};
class CMsgStore {
public:
CMsgStore( ULONG cbEid = 0, LPENTRYID lpEid = NULL);
~CMsgStore();
void SetEntryID( ULONG cbEid, LPENTRYID lpEid);
BOOL Open( LPMAPISESSION pSession, LPMDB *ppMdb);
ULONG GetCBEntryID( void) { return( m_cbEid);}
LPENTRYID GetLPEntryID( void) { return( (LPENTRYID) m_lpEid);}
private:
ULONG m_cbEid;
BYTE * m_lpEid;
LPMDB m_lpMdb;
};
class CMapiContentIter {
public:
virtual BOOL HandleContentItem( ULONG oType, ULONG cb, LPENTRYID pEntry) = 0;
};
class CMapiHierarchyIter {
public:
virtual BOOL HandleHierarchyItem( ULONG oType, ULONG cb, LPENTRYID pEntry) = 0;
};
class CMapiApi {
public:
CMapiApi();
~CMapiApi();
static BOOL LoadMapi( void);
static BOOL LoadMapiEntryPoints( void);
static void UnloadMapi( void);
static HINSTANCE m_hMapi32;
static void MAPIUninitialize( void);
static HRESULT MAPIInitialize( LPVOID lpInit);
static SCODE MAPIAllocateBuffer( ULONG cbSize, LPVOID FAR * lppBuffer);
static ULONG MAPIFreeBuffer( LPVOID lpBuff);
static HRESULT MAPILogonEx( ULONG ulUIParam, LPTSTR lpszProfileName, LPTSTR lpszPassword, FLAGS flFlags, LPMAPISESSION FAR * lppSession);
static HRESULT OpenStreamOnFile( LPALLOCATEBUFFER lpAllocateBuffer, LPFREEBUFFER lpFreeBuffer, ULONG ulFlags, LPTSTR lpszFileName, LPTSTR lpszPrefix, LPSTREAM FAR * lppStream);
static void FreeProws( LPSRowSet prows);
BOOL Initialize( void);
BOOL LogOn( void);
void AddMessageStore( CMsgStore *pStore);
void SetCurrentMsgStore( LPMDB lpMdb) { m_lpMdb = lpMdb;}
// Open any given entry from the current Message Store
BOOL OpenEntry( ULONG cbEntry, LPENTRYID pEntryId, LPUNKNOWN *ppOpen);
static BOOL OpenMdbEntry( LPMDB lpMdb, ULONG cbEntry, LPENTRYID pEntryId, LPUNKNOWN *ppOpen);
// Fill in the folders list with the heirarchy from the given
// message store.
BOOL GetStoreFolders( ULONG cbEid, LPENTRYID lpEid, CMapiFolderList& folders, int startDepth);
BOOL OpenStore( ULONG cbEid, LPENTRYID lpEid, LPMDB *ppMdb);
// Iteration
BOOL IterateStores( CMapiFolderList& list);
BOOL IterateContents( CMapiContentIter *pIter, LPMAPIFOLDER pFolder, ULONG flags = 0);
BOOL IterateHierarchy( CMapiHierarchyIter *pIter, LPMAPIFOLDER pFolder, ULONG flags = 0);
// Properties
static LPSPropValue GetMapiProperty( LPMAPIPROP pProp, ULONG tag);
static BOOL GetEntryIdFromProp( LPSPropValue pVal, ULONG& cbEntryId, LPENTRYID& lpEntryId, BOOL delVal = TRUE);
static BOOL GetStringFromProp( LPSPropValue pVal, nsCString& val, BOOL delVal = TRUE);
static LONG GetLongFromProp( LPSPropValue pVal, BOOL delVal = TRUE);
static BOOL GetLargeStringProperty( LPMAPIPROP pProp, ULONG tag, nsCString& val);
static BOOL IsLargeProperty( LPSPropValue pVal);
// Debugging & reporting stuff
static void ListProperties( LPMAPIPROP lpProp, BOOL getValues = TRUE);
static void ListPropertyValue( LPSPropValue pVal, nsCString& s);
protected:
BOOL HandleHierarchyItem( ULONG oType, ULONG cb, LPENTRYID pEntry);
BOOL HandleContentsItem( ULONG oType, ULONG cb, LPENTRYID pEntry);
void GetStoreInfo( CMapiFolder *pFolder, long *pSzContents);
// array of available message stores, cached so that
// message stores are only opened once, preventing multiple
// logon's by the user if the store requires a logon.
CMsgStore * FindMessageStore( ULONG cbEid, LPENTRYID lpEid);
void ClearMessageStores( void);
// Debugging & reporting stuff
static void GetPropTagName( ULONG tag, nsCString& s);
static void ReportStringProp( const char *pTag, LPSPropValue pVal);
static void ReportUIDProp( const char *pTag, LPSPropValue pVal);
static void ReportLongProp( const char *pTag, LPSPropValue pVal);
private:
nsVoidArray m_stores;
BOOL m_initialized;
LPMAPISESSION m_lpSession;
LPMDB m_lpMdb;
HRESULT m_lastError;
};
class CMapiFolderContents {
public:
CMapiFolderContents( LPMDB lpMdb, ULONG cbEID, LPENTRYID lpEid);
~CMapiFolderContents();
BOOL GetNext( ULONG *pcbEid, LPENTRYID *ppEid, ULONG *poType, BOOL *pDone);
ULONG GetCount( void) { return( m_count);}
protected:
BOOL SetUpIter( void);
private:
HRESULT m_lastError;
BOOL m_failure;
LPMDB m_lpMdb;
LPMAPIFOLDER m_lpFolder;
LPMAPITABLE m_lpTable;
ULONG m_fCbEid;
BYTE * m_fLpEid;
ULONG m_count;
ULONG m_iterCount;
BYTE * m_lastLpEid;
ULONG m_lastCbEid;
};
#endif /* MapiApi_h__ */

View File

@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef MapiDbgLog_h___
#define MapiDbgLog_h___
#ifdef NS_DEBUG
#define MAPI_DEBUG 1
#endif
#ifdef MAPI_DEBUG
#include "stdio.h"
#define MAPI_DUMP_STRING( x) printf( "%s", (const char *)x)
#define MAPI_TRACE0( x) printf( x)
#define MAPI_TRACE1( x, y) printf( x, y)
#define MAPI_TRACE2( x, y, z) printf( x, y, z)
#define MAPI_TRACE3( x, y, z, a) printf( x, y, z, a)
#define MAPI_TRACE4( x, y, z, a, b) printf( x, y, z, a, b)
#else
#define MAPI_DUMP_STRING( x)
#define MAPI_TRACE0( x)
#define MAPI_TRACE1( x, y)
#define MAPI_TRACE2( x, y, z)
#define MAPI_TRACE3( x, y, z, a)
#define MAPI_TRACE4( x, y, z, a, b)
#endif
#endif /* MapiDbgLog_h___ */

View File

@ -0,0 +1,764 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsString.h"
#include "nsFileSpec.h"
#include "MapiDbgLog.h"
#include "MapiApi.h"
#include "MapiMessage.h"
#include "MapiMimeTypes.h"
// needed for the call the OpenStreamOnFile
extern LPMAPIALLOCATEBUFFER gpMapiAllocateBuffer;
extern LPMAPIFREEBUFFER gpMapiFreeBuffer;
// Sample From line: From ????@???? 1 Jan 1965 00:00:00
typedef const char * PC_S8;
static const char * kWhitespace = "\b\t\r\n ";
static const char * sFromLine = "From ????@???? ";
static const char * sFromDate = "1 Jan 1965 00:00:00";
static const char * sDaysOfWeek[7] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char *sMonths[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
CMapiMessage::CMapiMessage( LPMESSAGE lpMsg)
{
m_lpMsg = lpMsg;
m_pAttachTable = NULL;
m_bMimeEncoding = FALSE;
m_bMimeVersion = FALSE;
m_ownsAttachFile = FALSE;
m_whitespace = kWhitespace;
}
CMapiMessage::~CMapiMessage()
{
if (m_pAttachTable)
m_pAttachTable->Release();
if (m_lpMsg)
m_lpMsg->Release();
ClearTempAttachFile();
}
void CMapiMessage::FormatDateTime( SYSTEMTIME & tm, nsCString& s, BOOL includeTZ)
{
long offset = _timezone;
s += sDaysOfWeek[tm.wDayOfWeek];
s += ", ";
s.Append( (PRInt32) tm.wDay);
s += " ";
s += sMonths[tm.wMonth - 1];
s += " ";
s.Append( (PRInt32) tm.wYear);
s += " ";
int val = tm.wHour;
if (val < 10)
s += "0";
s.Append( (PRInt32) val);
s += ":";
val = tm.wMinute;
if (val < 10)
s += "0";
s.Append( (PRInt32) val);
s += ":";
val = tm.wSecond;
if (val < 10)
s += "0";
s.Append( (PRInt32) val);
if (includeTZ) {
s += " ";
if (offset < 0) {
offset *= -1;
s += "+";
}
else
s += "-";
offset /= 60;
val = (int) (offset / 60);
if (val < 10)
s += "0";
s.Append( (PRInt32) val);
val = (int) (offset % 60);
if (val < 10)
s += "0";
s.Append( (PRInt32) val);
}
}
// Headers - fetch will get PR_TRANSPORT_MESSAGE_HEADERS
// or if they do not exist will build a header from
// PR_DISPLAY_TO, _CC, _BCC
// PR_SUBJECT
// PR_MESSAGE_RECIPIENTS
// and PR_CREATION_TIME if needed?
void CMapiMessage::BuildHeaders( void)
{
// Try to the to line.
m_headers.Truncate();
AddHeader( m_headers, PR_DISPLAY_TO, "To: ");
AddHeader( m_headers, PR_DISPLAY_CC, "CC: ");
AddHeader( m_headers, PR_DISPLAY_BCC, "BCC: ");
AddDate( m_headers);
AddSubject( m_headers);
AddFrom( m_headers);
}
BOOL CMapiMessage::AddHeader( nsCString& str, ULONG tag, const char *pPrefix)
{
nsCString value;
LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, tag);
if (CMapiApi::GetStringFromProp( pVal, value) && !value.IsEmpty()) {
str.Trim( kWhitespace, PR_FALSE, PR_TRUE);
if (!str.IsEmpty())
str += "\x0D\x0A";
str += pPrefix;
str += value;
return( TRUE);
}
return( FALSE);
}
void CMapiMessage::AddSubject( nsCString& str)
{
AddHeader( str, PR_SUBJECT, "Subject: ");
}
void CMapiMessage::AddFrom( nsCString& str)
{
if (!AddHeader( str, PR_SENDER_NAME, "From: "))
AddHeader( str, PR_SENDER_EMAIL_ADDRESS, "From: ");
}
void CMapiMessage::AddDate( nsCString& str)
{
LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_MESSAGE_DELIVERY_TIME);
if (!pVal)
pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_CREATION_TIME);
if (pVal) {
SYSTEMTIME st;
::FileTimeToSystemTime( &(pVal->Value.ft), &st);
CMapiApi::MAPIFreeBuffer( pVal);
str.Trim( kWhitespace, PR_FALSE, PR_TRUE);
if (!str.IsEmpty())
str += "\x0D\x0A";
str += "Date: ";
FormatDateTime( st, str);
}
}
void CMapiMessage::BuildFromLine( void)
{
m_fromLine = sFromLine;
LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_CREATION_TIME);
if (pVal) {
SYSTEMTIME st;
::FileTimeToSystemTime( &(pVal->Value.ft), &st);
CMapiApi::MAPIFreeBuffer( pVal);
FormatDateTime( st, m_fromLine, FALSE);
}
else
m_fromLine += sFromDate;
m_fromLine += "\x0D\x0A";
}
BOOL CMapiMessage::FetchHeaders( void)
{
LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_TRANSPORT_MESSAGE_HEADERS);
if (pVal && CMapiApi::IsLargeProperty( pVal)) {
m_headers.Truncate();
CMapiApi::GetLargeStringProperty( m_lpMsg, PR_TRANSPORT_MESSAGE_HEADERS, m_headers);
}
else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) {
m_headers = pVal->Value.LPSZ;
}
else {
// Need to build the headers from the other stuff
m_headers.Truncate();
BuildHeaders();
}
if (pVal)
CMapiApi::MAPIFreeBuffer( pVal);
m_fromLine.Truncate();
if (NeedsFromLine()) {
BuildFromLine();
}
if (!m_fromLine.IsEmpty()) {
MAPI_DUMP_STRING( m_fromLine);
}
MAPI_DUMP_STRING( m_headers);
MAPI_TRACE0( "\r\n");
ProcessHeaders();
if (!m_headers.IsEmpty()) {
if (!m_bHasSubject)
AddSubject( m_headers);
if (!m_bHasFrom)
AddFrom( m_headers);
if (!m_bHasDate)
AddDate( m_headers);
m_headers.Trim( kWhitespace, PR_FALSE, PR_TRUE);
m_headers += "\x0D\x0A";
}
#ifdef _DEBUG
// CMapiApi::ListProperties( m_lpMsg);
// MAPI_TRACE0( "--------------------\r\n");
#endif
return( !m_headers.IsEmpty());
}
// TRUE if a From line needs to precede the headers, FALSE
// if the headers already include a from line
BOOL CMapiMessage::NeedsFromLine( void)
{
nsCString l;
m_headers.Left( l, 5);
if (l == "From ")
return( FALSE);
else
return( TRUE);
}
BOOL CMapiMessage::IsMultipart( void)
{
nsCString left;
m_mimeContentType.Left( left, 10);
if (!left.Compare( "multipart/", PR_TRUE))
return( TRUE);
return( FALSE);
}
void CMapiMessage::GenerateBoundary( void)
{
m_mimeBoundary = "===============_NSImport_Boundary_";
PRUint32 t = ::GetTickCount();
nsCString hex;
hex.Append( (PRInt32) t, 16);
m_mimeBoundary += hex;
m_mimeBoundary += "====";
}
BOOL CMapiMessage::GetAttachFileLoc( nsIFileSpec * pLoc)
{
if (m_attachPath.IsEmpty())
return( FALSE);
pLoc->SetNativePath( (const char *) m_attachPath);
return( TRUE);
}
// Mime-Version: 1.0
// Content-Type: text/plain; charset="US-ASCII"
// Content-Type: multipart/mixed; boundary="=====================_874475278==_"
void CMapiMessage::ProcessHeaderLine( nsCString& line)
{
int len, start;
nsCString tStr;
nsCString left13;
nsCString left26;
nsCString left8;
nsCString left5;
line.Left( left13, 13);
line.Left( left26, 26);
line.Left( left8, 8);
line.Left( left5, 5);
if (!left13.Compare( "Mime-Version:", PR_TRUE))
m_bMimeVersion = TRUE;
else if (!left13.Compare( "Content-Type:", PR_TRUE)) {
// Note: this isn't a complete parser, the content type
// we extract could have rfc822 comments in it
len = 13;
while ((len < line.Length()) && IsSpace( line.CharAt( len)))
len++;
start = len;
while ((len < line.Length()) && (line.CharAt( len) != ';'))
len++;
line.Mid( m_mimeContentType, start, len - start);
len++;
// look for "boundary="
BOOL haveB;
BOOL haveC;
while (len < line.Length()) {
haveB = FALSE;
haveC = FALSE;
while ((len < line.Length()) && IsSpace( line.CharAt( len)))
len++;
start = len;
while ((len < line.Length()) && (line.CharAt( len) != '='))
len++;
if (len - start) {
line.Mid( tStr, start, len - start);
if (!tStr.Compare( "boundary", PR_TRUE))
haveB = TRUE;
else if (!tStr.Compare( "charset", PR_TRUE))
haveC = TRUE;
}
len++;
while ((len < line.Length()) && IsSpace( line.CharAt( len)))
len++;
if ((len < line.Length()) && (line.CharAt( len) == '"')) {
len++;
BOOL slash = FALSE;
tStr.Truncate();
while (len < line.Length()) {
if (slash) {
slash = FALSE;
tStr += line.CharAt( len);
}
else if (line.CharAt( len) == '"')
break;
else if (line.CharAt( len) != '\\')
tStr += line.CharAt( len);
else
slash = TRUE;
len++;
}
len++;
if (haveB) {
m_mimeBoundary = tStr;
haveB = FALSE;
}
if (haveC) {
m_mimeCharset = tStr;
haveC = FALSE;
}
}
tStr.Truncate();
while ((len < line.Length()) && (line.CharAt( len) != ';')) {
tStr += line.CharAt( len);
len++;
}
len++;
if (haveB) {
tStr.Trim( kWhitespace);
m_mimeBoundary = tStr;
}
if (haveC) {
tStr.Trim( kWhitespace);
m_mimeCharset = tStr;
}
}
}
else if (!left26.Compare( "Content-Transfer-Encoding:", PR_TRUE)) {
m_bMimeEncoding = TRUE;
}
else if (!left8.Compare( "Subject:", PR_TRUE))
m_bHasSubject = TRUE;
else if (!left5.Compare( "From:", PR_TRUE))
m_bHasFrom = TRUE;
else if (!left5.Compare( "Date: ", PR_TRUE))
m_bHasDate = TRUE;
}
void CMapiMessage::ProcessHeaders( void)
{
m_bHasSubject = FALSE;
m_bHasFrom = FALSE;
m_bHasDate = FALSE;
PC_S8 pChar = (PC_S8) m_headers;
int start = 0;
int len = 0;
nsCString line;
nsCString mid;
while (*pChar) {
if ((*pChar == 0x0D) && (*(pChar + 1) == 0x0A)) {
if ((*(pChar + 2) != ' ') && (*(pChar + 2) != 9)) {
m_headers.Mid( mid, start, len);
line += mid;
ProcessHeaderLine( line);
line.Truncate();
pChar++; // subsequent increment will move pChar to the next line
start += len;
start += 2;
len = -1;
}
}
pChar++;
len++;
}
if (!m_mimeContentType.IsEmpty() || !m_mimeBoundary.IsEmpty() || !m_mimeCharset.IsEmpty()) {
MAPI_TRACE1( "\tDecoded mime content type: %s\r\n", (PC_S8)m_mimeContentType);
MAPI_TRACE1( "\tDecoded mime boundary: %s\r\n", (PC_S8)m_mimeBoundary);
MAPI_TRACE1( "\tDecoded mime charset: %s\r\n", (PC_S8)m_mimeCharset);
}
}
BOOL CMapiMessage::FetchBody( void)
{
m_bodyIsHtml = FALSE;
m_body.Truncate();
LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_BODY);
if (!pVal) {
// Is it html?
pVal = CMapiApi::GetMapiProperty( m_lpMsg, 0x1013001e);
if (pVal && CMapiApi::IsLargeProperty( pVal))
CMapiApi::GetLargeStringProperty( m_lpMsg, 0x1013001e, m_body);
else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) {
m_body = pVal->Value.LPSZ;
}
if (!m_body.IsEmpty())
m_bodyIsHtml = TRUE;
}
else {
if (pVal && CMapiApi::IsLargeProperty( pVal)) {
CMapiApi::GetLargeStringProperty( m_lpMsg, PR_BODY, m_body);
}
else {
if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) {
m_body = pVal->Value.LPSZ;
}
}
}
if (pVal)
CMapiApi::MAPIFreeBuffer( pVal);
MAPI_DUMP_STRING( m_body);
MAPI_TRACE0( "\r\n");
return( TRUE);
}
enum {
ieidPR_ATTACH_NUM = 0,
ieidAttachMax
};
static const SizedSPropTagArray(ieidAttachMax, ptaEid)=
{
ieidAttachMax,
{
PR_ATTACH_NUM
}
};
int CMapiMessage::CountAttachments( void)
{
m_attachNums.RemoveAll();
LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_HASATTACH);
BOOL has = TRUE;
if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_BOOLEAN)) {
has = (pVal->Value.b != 0);
}
if (pVal)
CMapiApi::MAPIFreeBuffer( pVal);
if (has) {
// Get the attachment table?
HRESULT hr;
LPMAPITABLE pTable = NULL;
hr = m_lpMsg->GetAttachmentTable( 0, &pTable);
if (FAILED( hr))
return( 0);
m_pAttachTable = pTable;
IterateAttachTable();
}
return( m_attachNums.GetSize());
}
BOOL CMapiMessage::IterateAttachTable( void)
{
LPMAPITABLE lpTable = m_pAttachTable;
ULONG rowCount;
HRESULT hr = lpTable->GetRowCount( 0, &rowCount);
if (!rowCount) {
return( TRUE);
}
hr = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0);
if (FAILED(hr)) {
MAPI_TRACE2( "SetColumns for attachment table failed: 0x%lx, %d\r\n", (long)hr, (int)hr);
return( FALSE);
}
hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL);
if (FAILED(hr)) {
MAPI_TRACE2( "SeekRow for attachment table failed: 0x%lx, %d\r\n", (long)hr, (int)hr);
return( FALSE);
}
int cNumRows = 0;
LPSRowSet lpRow;
BOOL bResult = TRUE;
do {
lpRow = NULL;
hr = lpTable->QueryRows( 1, 0, &lpRow);
if(HR_FAILED(hr)) {
MAPI_TRACE2( "QueryRows for attachment table failed: 0x%lx, %d\n", (long)hr, (int)hr);
bResult = FALSE;
break;
}
if(lpRow) {
cNumRows = lpRow->cRows;
if (cNumRows) {
LONG aNum = lpRow->aRow[0].lpProps[ieidPR_ATTACH_NUM].Value.l;
m_attachNums.Add( (PRUint32)aNum);
MAPI_TRACE1( "\t\t****Attachment found - #%d\r\n", (int)aNum);
}
CMapiApi::FreeProws( lpRow);
}
} while ( SUCCEEDED(hr) && cNumRows && lpRow);
return( bResult);
}
void CMapiMessage::ClearTempAttachFile( void)
{
if (m_ownsAttachFile && !m_attachPath.IsEmpty()) {
nsFileSpec spec( (const char *)m_attachPath);
spec.Delete( PR_FALSE);
}
m_ownsAttachFile = FALSE;
m_attachPath.Truncate();
}
BOOL CMapiMessage::CopyBinAttachToFile( LPATTACH lpAttach)
{
LPSTREAM lpStreamFile;
char tPath[256];
DWORD len;
if (!(len = ::GetTempPath( 256, tPath)) || (len > 200)) {
len = 3;
strcpy( tPath, "c:\\");
}
if (tPath[len - 1] != '\\')
strcat( tPath, "\\");
m_ownsAttachFile = FALSE;
m_attachPath.Truncate();
HRESULT hr = CMapiApi::OpenStreamOnFile( gpMapiAllocateBuffer, gpMapiFreeBuffer, STGM_READWRITE | STGM_CREATE | SOF_UNIQUEFILENAME,
tPath, NULL, &lpStreamFile);
if (HR_FAILED(hr)) {
MAPI_TRACE1( "~~ERROR~~ OpenStreamOnFile failed - temp path: %s\r\n", tPath);
return( FALSE);
}
m_attachPath = tPath;
MAPI_TRACE1( "\t\t** Attachment extracted to temp file: %s\r\n", (const char *)m_attachPath);
BOOL bResult = TRUE;
LPSTREAM lpAttachStream;
hr = lpAttach->OpenProperty( PR_ATTACH_DATA_BIN, &IID_IStream, 0, 0, (LPUNKNOWN *)&lpAttachStream);
if (HR_FAILED( hr)) {
MAPI_TRACE0( "~~ERROR~~ OpenProperty failed for PR_ATTACH_DATA_BIN.\r\n");
lpAttachStream = NULL;
bResult = FALSE;
}
else {
STATSTG st;
hr = lpAttachStream->Stat( &st, STATFLAG_NONAME);
if (HR_FAILED( hr)) {
MAPI_TRACE0( "~~ERROR~~ Stat failed for attachment stream\r\n");
bResult = FALSE;
}
else {
hr = lpAttachStream->CopyTo( lpStreamFile, st.cbSize, NULL, NULL);
if (HR_FAILED( hr)) {
MAPI_TRACE0( "~~ERROR~~ Attach Stream CopyTo temp file failed.\r\n");
bResult = FALSE;
}
}
}
if (lpAttachStream)
lpAttachStream->Release();
lpStreamFile->Release();
if (!bResult) {
nsFileSpec spec( (const char *)m_attachPath);
spec.Delete( PR_FALSE);
}
else
m_ownsAttachFile = TRUE;
return( bResult);
}
BOOL CMapiMessage::GetAttachmentInfo( int idx)
{
ClearTempAttachFile();
BOOL bResult = TRUE;
if ((idx < 0) || (idx >= (int)m_attachNums.GetSize())) {
return( FALSE);
}
DWORD aNum = m_attachNums.GetAt( idx);
LPATTACH lpAttach = NULL;
HRESULT hr = m_lpMsg->OpenAttach( aNum, NULL, 0, &lpAttach);
if (HR_FAILED( hr)) {
MAPI_TRACE2( "\t\t****Attachment error, unable to open attachment: %d, 0x%lx\r\n", idx, hr);
return( FALSE);
}
LPSPropValue pVal;
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_MIME_TAG);
if (pVal)
CMapiApi::GetStringFromProp( pVal, m_attachMimeType);
else
m_attachMimeType.Truncate();
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_METHOD);
if (pVal) {
LONG aMethod = CMapiApi::GetLongFromProp( pVal);
if ((aMethod == ATTACH_BY_REF_ONLY) || (aMethod == ATTACH_BY_REFERENCE) || (aMethod == ATTACH_BY_REF_RESOLVE)) {
m_attachPath.Truncate();
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_PATHNAME);
if (pVal)
CMapiApi::GetStringFromProp( pVal, m_attachPath);
MAPI_TRACE2( "\t\t** Attachment #%d by ref: %s\r\n", idx, (const char *)m_attachPath);
m_ownsAttachFile = FALSE;
}
else if (aMethod == ATTACH_BY_VALUE) {
MAPI_TRACE1( "\t\t** Attachment #%d by value.\r\n", idx);
bResult = CopyBinAttachToFile( lpAttach);
}
else if (aMethod == ATTACH_OLE) {
MAPI_TRACE1( "\t\t** Attachment #%d by OLE - yuck!!!\r\n", idx);
}
else if (aMethod == ATTACH_EMBEDDED_MSG) {
MAPI_TRACE1( "\t\t** Attachment #%d by Embedded Message??\r\n", idx);
}
else {
MAPI_TRACE2( "\t\t** Attachment #%d unknown attachment method - 0x%lx\r\n", idx, aMethod);
bResult = FALSE;
}
}
else
bResult = FALSE;
nsCString fName, fExt;
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_FILENAME);
if (pVal)
CMapiApi::GetStringFromProp( pVal, fName);
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_EXTENSION);
if (pVal)
CMapiApi::GetStringFromProp( pVal, fExt);
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_SIZE);
long sz = 0;
if (pVal)
sz = CMapiApi::GetLongFromProp( pVal);
/*
// I have no idea how this tag is used, how to interpret it's value, etc.
// Fortunately, the Microsoft documentation is ABSOLUTELY NO HELP AT ALL. In fact,
// if one goes by the docs and sample code, this tag is completely 100% useless. I'm
// sure it has some important meaning which will one day be obvious, but for now,
// it is ignored.
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_TAG);
if (pVal) {
::MAPIFreeBuffer( pVal);
}
*/
MAPI_TRACE1( "\t\t\t--- Mime type: %s\r\n", (const char *)m_attachMimeType);
MAPI_TRACE2( "\t\t\t--- File name: %s, extension: %s\r\n", (const char *)fName, (const char *)fExt);
MAPI_TRACE1( "\t\t\t--- Size: %ld\r\n", sz);
if (fExt.IsEmpty()) {
int idx = fName.RFindChar( '.');
if (idx != -1)
fName.Right( fExt, fName.Length() - idx);
}
if ((fName.RFindChar( '.') == -1) && !fExt.IsEmpty()) {
fName += ".";
fName += fExt;
}
m_attachFileName = fName;
if (m_attachMimeType.IsEmpty()) {
PRUint8 *pType = NULL;
if (!fExt.IsEmpty()) {
pType = CMimeTypes::GetMimeType( fExt);
}
if (pType)
m_attachMimeType = (PC_S8)pType;
else
m_attachMimeType = "application/octet-stream";
}
pVal = CMapiApi::GetMapiProperty( lpAttach, PR_ATTACH_TRANSPORT_NAME);
if (pVal) {
CMapiApi::GetStringFromProp( pVal, fName);
MAPI_TRACE1( "\t\t\t--- Transport name: %s\r\n", (const char *)fName);
}
lpAttach->Release();
return( bResult);
}
void nsSimpleUInt32Array::Allocate( void)
{
if (m_used < m_allocated)
return;
if (!m_pData) {
m_pData = new PRUint32[m_growBy];
m_allocated = m_growBy;
}
else {
m_allocated += m_growBy;
PRUint32 *pData = new PRUint32[m_allocated];
nsCRT::memcpy( pData, m_pData, (m_allocated - m_growBy) * sizeof( PRUint32));
delete [] m_pData;
m_pData = pData;
}
}

View File

@ -0,0 +1,135 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef MapiMessage_h___
#define MapiMessage_h___
#include "nsUInt32Array.h"
#include "nsString.h"
#include "MapiApi.h"
class nsSimpleUInt32Array {
public:
nsSimpleUInt32Array( int growBy = 20)
{ m_growBy = growBy; m_pData = nsnull; m_used = 0; m_allocated = 0;}
~nsSimpleUInt32Array() { if (m_pData) delete [] m_pData;}
void Add( PRUint32 data) { Allocate(); if (m_used < m_allocated) { m_pData[m_used] = data; m_used++;}}
PRUint32 GetAt( PRInt32 index) { if ((index >= 0) && (index < m_used)) return( m_pData[index]); else return( 0);}
PRInt32 GetSize( void) { return( m_used);}
void RemoveAll( void) { m_used = 0;}
private:
void Allocate( void);
PRInt32 m_allocated;
PRInt32 m_used;
PRUint32 * m_pData;
int m_growBy;
};
class CMapiMessage {
public:
CMapiMessage( LPMESSAGE lpMsg);
~CMapiMessage();
// Headers - fetch will get PR_TRANSPORT_MESSAGE_HEADERS
// or if they do not exist will build a header from
// PR_DISPLAY_TO, _CC, _BCC
// PR_SUBJECT
// PR_MESSAGE_RECIPIENTS
// and PR_CREATION_TIME if needed?
BOOL FetchHeaders( void);
// Do the headers need a From separator line.
// TRUE if a From line needs to precede the headers, FALSE
// if the headers already include a from line
BOOL NeedsFromLine( void);
// Fetch the
BOOL FetchBody( void);
// Attachments
int CountAttachments( void);
BOOL GetAttachmentInfo( int idx);
// Retrieve info for message
BOOL BodyIsHtml( void) { return( m_bodyIsHtml);}
const char *GetFromLine( int& len) { if (m_fromLine.IsEmpty()) return( NULL); else { len = m_fromLine.Length(); return( (const char *)m_fromLine);}}
const char *GetHeaders( int& len) { if (m_headers.IsEmpty()) return( NULL); else { len = m_headers.Length(); return( (const char *)m_headers);}}
const char *GetBody( int& len) { if (m_body.IsEmpty()) return( NULL); else { len = m_body.Length(); return( (const char *)m_body);}}
BOOL IsMultipart( void);
BOOL HasContentHeader( void) { return( !m_mimeContentType.IsEmpty());}
BOOL HasMimeVersion( void) { return( m_bMimeVersion);}
const char *GetMimeContent( void) { return( (const char *)m_mimeContentType);}
const char *GetMimeBoundary( void) { return( (const char *)m_mimeBoundary);}
void GenerateBoundary( void);
BOOL GetAttachFileLoc( nsIFileSpec *pLoc);
const char *GetMimeType( void) { return( (const char *) m_attachMimeType);}
const char *GetFileName( void) { return( (const char *) m_attachFileName);}
protected:
BOOL IterateAttachTable( void);
void ClearTempAttachFile( void);
BOOL CopyBinAttachToFile( LPATTACH lpAttach);
void ProcessHeaderLine( nsCString& line);
void ProcessHeaders( void);
void FormatDateTime( SYSTEMTIME & tm, nsCString& s, BOOL includeTZ = TRUE);
void BuildHeaders( void);
void BuildFromLine( void);
void AddSubject( nsCString& str);
void AddFrom( nsCString& str);
BOOL AddHeader( nsCString& str, ULONG tag, const char *pPrefix);
void AddDate( nsCString& str);
BOOL IsSpace( PRUnichar c) { return( m_whitespace.FindChar( c) != -1);}
private:
LPMESSAGE m_lpMsg;
LPMAPITABLE m_pAttachTable;
nsCString m_headers;
nsCString m_fromLine;
nsCString m_body;
nsCString m_mimeContentType;
nsCString m_mimeBoundary;
nsCString m_mimeCharset;
BOOL m_bMimeVersion;
BOOL m_bMimeEncoding;
nsSimpleUInt32Array m_attachNums;
nsCString m_attachMimeType;
nsCString m_attachPath;
nsCString m_attachFileName;
BOOL m_ownsAttachFile;
BOOL m_bodyIsHtml;
BOOL m_bHasSubject;
BOOL m_bHasFrom;
BOOL m_bHasDate;
nsCString m_whitespace;
};
#endif /* MapiMessage_h__ */

View File

@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsCRT.h"
#include "nsString.h"
#include "MapiMimeTypes.h"
PRUint8 CMimeTypes::m_mimeBuffer[kMaxMimeTypeSize];
BOOL CMimeTypes::GetKey( HKEY root, LPCTSTR pName, PHKEY pKey)
{
LONG result = RegOpenKeyEx( root, pName, 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, pKey);
return (result == ERROR_SUCCESS);
}
BOOL CMimeTypes::GetValueBytes( HKEY rootKey, LPCTSTR pValName, LPBYTE *ppBytes)
{
LONG err;
DWORD bufSz;
*ppBytes = NULL;
// Get the installed directory
err = RegQueryValueEx( rootKey, pValName, NULL, NULL, NULL, &bufSz);
if (err == ERROR_SUCCESS) {
*ppBytes = new BYTE[bufSz];
err = RegQueryValueEx( rootKey, pValName, NULL, NULL, *ppBytes, &bufSz);
if (err == ERROR_SUCCESS) {
return( TRUE);
}
delete *ppBytes;
*ppBytes = NULL;
}
return( FALSE);
}
void CMimeTypes::ReleaseValueBytes( LPBYTE pBytes)
{
if (pBytes)
delete pBytes;
}
BOOL CMimeTypes::GetMimeTypeFromReg( const nsCString& ext, LPBYTE *ppBytes)
{
HKEY extensionKey;
BOOL result = FALSE;
*ppBytes = NULL;
if (GetKey( HKEY_CLASSES_ROOT, ext, &extensionKey)) {
result = GetValueBytes( extensionKey, "Content Type", ppBytes);
RegCloseKey( extensionKey);
}
return( result);
}
PRUint8 * CMimeTypes::GetMimeType( nsCString& theExt)
{
nsCString ext = theExt;
if (ext.Length()) {
if (ext.First() != '.') {
ext = ".";
ext += theExt;
}
}
BOOL result = FALSE;
int len;
if (!ext.Length())
return( NULL);
LPBYTE pByte;
if (GetMimeTypeFromReg( ext, &pByte)) {
len = nsCRT::strlen( (const char *) pByte);
if (len && (len < kMaxMimeTypeSize)) {
nsCRT::memcpy( m_mimeBuffer, pByte, len);
m_mimeBuffer[len] = 0;
result = TRUE;
}
ReleaseValueBytes( pByte);
}
if (result)
return( m_mimeBuffer);
return( NULL);
}

View File

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef MapiMimeTypes_h___
#define MapiMimeTypes_h___
#include <windows.h>
#define kMaxMimeTypeSize 256
class CMimeTypes {
public:
static PRUint8 * GetMimeType( nsCString& theExt);
protected:
// Registry stuff
static BOOL GetKey( HKEY root, LPCTSTR pName, PHKEY pKey);
static BOOL GetValueBytes( HKEY rootKey, LPCTSTR pValName, LPBYTE *ppBytes);
static void ReleaseValueBytes( LPBYTE pBytes);
static BOOL GetMimeTypeFromReg( const nsCString& ext, LPBYTE *ppBytes);
static PRUint8 m_mimeBuffer[kMaxMimeTypeSize];
};
#endif /* MapiMimeTypes_h__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef OutlookDebugLog_h___
#define OutlookDebugLog_h___
#ifdef NS_DEBUG
#define IMPORT_DEBUG 1
#endif
#ifdef IMPORT_DEBUG
#include "stdio.h"
#define IMPORT_LOG0( x) printf( x)
#define IMPORT_LOG1( x, y) printf( x, y)
#define IMPORT_LOG2( x, y, z) printf( x, y, z)
#define IMPORT_LOG3( a, b, c, d) printf( a, b, c, d)
#else
#define IMPORT_LOG0( x)
#define IMPORT_LOG1( x, y)
#define IMPORT_LOG2( x, y, z)
#define IMPORT_LOG3( a, b, c, d)
#endif
#endif /* OutlookDebugLog_h___ */

View File

@ -0,0 +1,49 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..\..
MODULE=impOutlk
MAKE_OBJ_TYPE=DLL
DLLNAME=$(MODULE)
DLL=.\$(OBJDIR)\$(DLLNAME).dll
CPP_OBJS=\
.\$(OBJDIR)\nsOutlookFactory.obj \
.\$(OBJDIR)\nsOutlookRegUtil.obj \
.\$(OBJDIR)\nsOutlookStringBundle.obj \
.\$(OBJDIR)\nsOutlookImport.obj \
.\$(OBJDIR)\nsOutlookSettings.obj \
.\$(OBJDIR)\MapiApi.obj \
.\$(OBJDIR)\nsOutlookMail.obj \
.\$(OBJDIR)\MapiMessage.obj \
.\$(OBJDIR)\MapiMimeTypes.obj \
$(NULL)
LLIBS=\
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\plc3.lib \
$(LIBNSPR) \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) $(DLL) $(DIST)\bin\components

View File

@ -0,0 +1,352 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Outlook (Win32) import module
*/
#include "nsCOMPtr.h"
#include "nsIModule.h"
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsIRegistry.h"
#include "nsIImportService.h"
#include "nsOutlookImport.h"
#include "OutlookDebugLog.h"
static NS_DEFINE_CID(kOutlookImportCID, NS_OUTLOOKIMPORT_CID);
static NS_DEFINE_CID(kImportServiceCID, NS_IMPORTSERVICE_CID);
static NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID);
// Module implementation for the Outlook Express import library
class nsOutlookImportModule : public nsIModule
{
public:
nsOutlookImportModule();
virtual ~nsOutlookImportModule();
NS_DECL_ISUPPORTS
NS_DECL_NSIMODULE
protected:
nsresult Initialize();
void Shutdown();
PRBool mInitialized;
nsCOMPtr<nsIGenericFactory> mFactory;
};
//----------------------------------------------------------------------
// Functions used to create new instances of a given object by the
// generic factory.
#define MAKE_CTOR(_iface, _name) \
static NS_IMETHODIMP \
CreateNew##_name(nsISupports* aOuter, REFNSIID aIID, void **aResult) \
{ \
if (!aResult) { \
return NS_ERROR_INVALID_POINTER; \
} \
if (aOuter) { \
*aResult = nsnull; \
return NS_ERROR_NO_AGGREGATION; \
} \
nsI##_iface* inst; \
nsresult rv = NS_New##_name(&inst); \
if (NS_FAILED(rv)) { \
*aResult = nsnull; \
return rv; \
} \
rv = inst->QueryInterface(aIID, aResult); \
if (NS_FAILED(rv)) { \
*aResult = nsnull; \
} \
NS_RELEASE(inst); /* get rid of extra refcnt */ \
return rv; \
}
MAKE_CTOR(ImportModule, OutlookImport)
//----------------------------------------------------------------------
static NS_DEFINE_IID(kIModuleIID, NS_IMODULE_IID);
nsOutlookImportModule::nsOutlookImportModule()
: mInitialized(PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
nsOutlookImportModule::~nsOutlookImportModule()
{
Shutdown();
}
NS_IMPL_ISUPPORTS(nsOutlookImportModule, kIModuleIID)
// Perform our one-time intialization for this module
nsresult
nsOutlookImportModule::Initialize()
{
if (mInitialized) {
return NS_OK;
}
mInitialized = PR_TRUE;
return NS_OK;
}
// Shutdown this module, releasing all of the module resources
void
nsOutlookImportModule::Shutdown()
{
// Release the factory object
mFactory = nsnull;
}
// Create a factory object for creating instances of aClass.
NS_IMETHODIMP
nsOutlookImportModule::GetClassObject(nsIComponentManager *aCompMgr,
const nsCID& aClass,
const nsIID& aIID,
void** r_classObj)
{
nsresult rv;
// Defensive programming: Initialize *r_classObj in case of error below
if (!r_classObj) {
return NS_ERROR_INVALID_POINTER;
}
*r_classObj = NULL;
// Do one-time-only initialization if necessary
if (!mInitialized) {
rv = Initialize();
if (NS_FAILED(rv)) {
// Initialization failed! yikes!
return rv;
}
}
// Choose the appropriate factory, based on the desired instance
// class type (aClass).
nsCOMPtr<nsIGenericFactory> fact;
if (aClass.Equals(kOutlookImportCID)) {
if (!mFactory) {
// Create and save away the factory object for creating
// new instances of Sample. This way if we are called
// again for the factory, we won't need to create a new
// one.
rv = NS_NewGenericFactory(getter_AddRefs(mFactory),
CreateNewOutlookImport);
}
fact = mFactory;
}
else {
rv = NS_ERROR_FACTORY_NOT_REGISTERED;
#ifdef DEBUG
char* cs = aClass.ToString();
printf("+++ nsOutlookImportModule: unable to create factory for %s\n", cs);
nsCRT::free(cs);
#endif
}
if (fact) {
rv = fact->QueryInterface(aIID, r_classObj);
}
return rv;
}
//----------------------------------------
struct Components {
const char* mDescription;
const nsID* mCID;
const char* mProgID;
};
// The list of components we register
static Components gComponents[] = {
{ "Outlook Import Component", &kOutlookImportCID,
"component://mozilla/import/import-outlook", },
};
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]))
nsresult GetImportModulesRegKey( nsIRegistry *reg, nsRegistryKey *pKey)
{
nsRegistryKey nScapeKey;
nsresult rv = reg->GetSubtree( nsIRegistry::Common, "Netscape", &nScapeKey);
if (NS_FAILED(rv)) {
rv = reg->AddSubtree( nsIRegistry::Common, "Netscape", &nScapeKey);
}
if (NS_FAILED( rv))
return( rv);
nsRegistryKey iKey;
rv = reg->GetSubtree( nScapeKey, "Import", &iKey);
if (NS_FAILED( rv)) {
rv = reg->AddSubtree( nScapeKey, "Import", &iKey);
}
if (NS_FAILED( rv))
return( rv);
rv = reg->GetSubtree( iKey, "Modules", pKey);
if (NS_FAILED( rv)) {
rv = reg->AddSubtree( iKey, "Modules", pKey);
}
return( rv);
}
NS_IMETHODIMP
nsOutlookImportModule::RegisterSelf(nsIComponentManager *aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation,
const char* componentType)
{
nsresult rv = NS_OK;
#ifdef DEBUG
printf("*** Registering Outlook import components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
rv = aCompMgr->RegisterComponentSpec(*cp->mCID, cp->mDescription,
cp->mProgID, aPath, PR_TRUE,
PR_TRUE);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsOutlookImportModule: unable to register %s component => %x\n",
cp->mDescription, rv);
#endif
break;
}
cp++;
}
{
NS_WITH_SERVICE( nsIRegistry, reg, kRegistryCID, &rv);
if (NS_FAILED(rv)) {
IMPORT_LOG0( "*** Import Outlook, ERROR GETTING THE Registry\n");
return rv;
}
rv = reg->OpenDefault();
if (NS_FAILED(rv)) {
IMPORT_LOG0( "*** Import Outlook, ERROR OPENING THE REGISTRY\n");
return( rv);
}
nsRegistryKey importKey;
rv = GetImportModulesRegKey( reg, &importKey);
if (NS_FAILED( rv)) {
IMPORT_LOG0( "*** Import Outlook, ERROR getting Netscape/Import registry key\n");
return( rv);
}
nsRegistryKey key;
rv = reg->AddSubtree( importKey, "Outlook", &key);
if (NS_FAILED(rv)) return( rv);
rv = reg->SetString( key, "Supports", kOutlookSupportsString);
if (NS_FAILED(rv)) return( rv);
char *myCID = kOutlookImportCID.ToString();
rv = reg->SetString( key, "CLSID", myCID);
delete [] myCID;
if (NS_FAILED(rv)) return( rv);
}
return rv;
}
NS_IMETHODIMP
nsOutlookImportModule::UnregisterSelf(nsIComponentManager* aCompMgr,
nsIFileSpec* aPath,
const char* registryLocation)
{
#ifdef DEBUG
printf("*** Unregistering Outlook import components\n");
#endif
Components* cp = gComponents;
Components* end = cp + NUM_COMPONENTS;
while (cp < end) {
nsresult rv = aCompMgr->UnregisterComponentSpec(*cp->mCID, aPath);
if (NS_FAILED(rv)) {
#ifdef DEBUG
printf("nsOutlookImportModule: unable to unregister %s component => %x\n",
cp->mDescription, rv);
#endif
}
cp++;
}
return NS_OK;
}
NS_IMETHODIMP
nsOutlookImportModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
{
if (!okToUnload) {
return NS_ERROR_INVALID_POINTER;
}
*okToUnload = PR_FALSE;
return NS_ERROR_FAILURE;
}
//----------------------------------------------------------------------
static nsOutlookImportModule *gModule = NULL;
extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
nsIFileSpec* location,
nsIModule** return_cobj)
{
nsresult rv = NS_OK;
NS_ASSERTION(return_cobj, "Null argument");
NS_ASSERTION(gModule == NULL, "nsOutlookImportModule: Module already created.");
// Create an initialize the layout module instance
nsOutlookImportModule *m = new nsOutlookImportModule();
if (!m) {
return NS_ERROR_OUT_OF_MEMORY;
}
// Increase refcnt and store away nsIModule interface to m in return_cobj
rv = m->QueryInterface(nsIModule::GetIID(), (void**)return_cobj);
if (NS_FAILED(rv)) {
delete m;
m = nsnull;
}
gModule = m; // WARNING: Weak Reference
return rv;
}

View File

@ -0,0 +1,571 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Outlook Express (Win32) import mail and addressbook interfaces
*/
#include "nscore.h"
#include "nsCRT.h"
#include "nsString.h"
#include "nsIServiceManager.h"
#include "nsIImportService.h"
#include "nsComponentManagerUtils.h"
#include "nsOutlookImport.h"
#include "nsIAllocator.h"
#include "nsIImportService.h"
#include "nsIImportMail.h"
#include "nsIImportMailboxDescriptor.h"
#include "nsIImportGeneric.h"
#include "nsIImportAddressBooks.h"
#include "nsIImportABDescriptor.h"
#include "nsIOutputStream.h"
#include "nsIAddrDatabase.h"
#include "nsOutlookSettings.h"
#include "nsTextFormater.h"
#include "nsOutlookStringBundle.h"
#include "OutlookDebugLog.h"
#include "nsOutlookMail.h"
static NS_DEFINE_CID(kImportServiceCID, NS_IMPORTSERVICE_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
class ImportMailImpl : public nsIImportMail
{
public:
ImportMailImpl();
virtual ~ImportMailImpl();
static nsresult Create(nsIImportMail** aImport);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIImportmail interface
/* void GetDefaultLocation (out nsIFileSpec location, out boolean found, out boolean userVerify); */
NS_IMETHOD GetDefaultLocation(nsIFileSpec **location, PRBool *found, PRBool *userVerify);
/* nsISupportsArray FindMailboxes (in nsIFileSpec location); */
NS_IMETHOD FindMailboxes(nsIFileSpec *location, nsISupportsArray **_retval);
/* void ImportMailbox (in nsIImportMailboxDescriptor source, in nsIFileSpec destination, out boolean fatalError); */
NS_IMETHOD ImportMailbox(nsIImportMailboxDescriptor *source, nsIFileSpec *destination,
PRUnichar **pErrorLog, PRUnichar **pSuccessLog, PRBool *fatalError);
/* unsigned long GetImportProgress (); */
NS_IMETHOD GetImportProgress(PRUint32 *_retval);
private:
static void ReportSuccess( nsString& name, PRInt32 count, nsString *pStream);
static void ReportError( PRInt32 errorNum, nsString& name, nsString *pStream);
static void AddLinebreak( nsString *pStream);
static void SetLogs( nsString& success, nsString& error, PRUnichar **pError, PRUnichar **pSuccess);
private:
nsOutlookMail m_mail;
};
class ImportAddressImpl : public nsIImportAddressBooks
{
public:
ImportAddressImpl();
virtual ~ImportAddressImpl();
static nsresult Create(nsIImportAddressBooks** aImport);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIImportAddressBooks interface
/* PRBool GetSupportsMultiple (); */
NS_IMETHOD GetSupportsMultiple(PRBool *_retval) { *_retval = PR_FALSE; return( NS_OK);}
/* PRBool GetAutoFind (out wstring description); */
NS_IMETHOD GetAutoFind(PRUnichar **description, PRBool *_retval);
/* PRBool GetNeedsFieldMap (); */
NS_IMETHOD GetNeedsFieldMap(PRBool *_retval) { *_retval = PR_FALSE; return( NS_OK);}
/* void GetDefaultLocation (out nsIFileSpec location, out boolean found, out boolean userVerify); */
NS_IMETHOD GetDefaultLocation(nsIFileSpec **location, PRBool *found, PRBool *userVerify)
{ return( NS_ERROR_FAILURE);}
/* nsISupportsArray FindAddressBooks (in nsIFileSpec location); */
NS_IMETHOD FindAddressBooks(nsIFileSpec *location, nsISupportsArray **_retval);
/* nsISupports GetFieldMap (in nsIImportABDescriptor source); */
NS_IMETHOD GetFieldMap(nsIImportABDescriptor *source, nsISupports **_retval)
{ return( NS_ERROR_FAILURE); }
/* void ImportAddressBook (in nsIImportABDescriptor source, in nsISupports destination, in nsISupports fieldMap, out boolean fatalError); */
NS_IMETHOD ImportAddressBook( nsIImportABDescriptor *source,
nsIAddrDatabase * destination,
nsISupports * fieldMap,
PRUnichar ** errorLog,
PRUnichar ** successLog,
PRBool * fatalError);
/* unsigned long GetImportProgress (); */
NS_IMETHOD GetImportProgress(PRUint32 *_retval);
private:
void GetOEInterface( void);
private:
nsIImportAddressBooks * m_pWabImport;
};
////////////////////////////////////////////////////////////////////////
nsresult NS_NewOutlookImport(nsIImportModule** aImport)
{
NS_PRECONDITION(aImport != nsnull, "null ptr");
if (! aImport)
return NS_ERROR_NULL_POINTER;
*aImport = new nsOutlookImport();
if (! *aImport)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aImport);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsOutlookImport::nsOutlookImport()
{
NS_INIT_REFCNT();
IMPORT_LOG0( "nsOutlookImport Module Created\n");
}
nsOutlookImport::~nsOutlookImport()
{
IMPORT_LOG0( "nsOutlookImport Module Deleted\n");
}
NS_IMPL_ISUPPORTS(nsOutlookImport, nsIImportModule::GetIID());
NS_IMETHODIMP nsOutlookImport::GetName( PRUnichar **name)
{
NS_PRECONDITION(name != nsnull, "null ptr");
if (! name)
return NS_ERROR_NULL_POINTER;
// nsString title = "Outlook Express";
// *name = title.ToNewUnicode();
*name = nsOutlookStringBundle::GetStringByID( OUTLOOKIMPORT_NAME);
return NS_OK;
}
NS_IMETHODIMP nsOutlookImport::GetDescription( PRUnichar **name)
{
NS_PRECONDITION(name != nsnull, "null ptr");
if (! name)
return NS_ERROR_NULL_POINTER;
// nsString desc = "Outlook Express mail and address books";
// *name = desc.ToNewUnicode();
*name = nsOutlookStringBundle::GetStringByID( OUTLOOKIMPORT_DESCRIPTION);
return NS_OK;
}
NS_IMETHODIMP nsOutlookImport::GetSupports( char **supports)
{
NS_PRECONDITION(supports != nsnull, "null ptr");
if (! supports)
return NS_ERROR_NULL_POINTER;
*supports = nsCRT::strdup( kOutlookSupportsString);
return( NS_OK);
}
NS_IMETHODIMP nsOutlookImport::GetImportInterface( const char *pImportType, nsISupports **ppInterface)
{
NS_PRECONDITION(pImportType != nsnull, "null ptr");
if (! pImportType)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(ppInterface != nsnull, "null ptr");
if (! ppInterface)
return NS_ERROR_NULL_POINTER;
*ppInterface = nsnull;
nsresult rv;
if (!nsCRT::strcmp( pImportType, "mail")) {
// create the nsIImportMail interface and return it!
nsIImportMail * pMail = nsnull;
nsIImportGeneric *pGeneric = nsnull;
rv = ImportMailImpl::Create( &pMail);
if (NS_SUCCEEDED( rv)) {
NS_WITH_SERVICE( nsIImportService, impSvc, kImportServiceCID, &rv);
if (NS_SUCCEEDED( rv)) {
rv = impSvc->CreateNewGenericMail( &pGeneric);
if (NS_SUCCEEDED( rv)) {
pGeneric->SetData( "mailInterface", pMail);
nsString name;
nsOutlookStringBundle::GetStringByID( OUTLOOKIMPORT_NAME, name);
pGeneric->SetData( "name", (nsISupports *) name.GetUnicode());
rv = pGeneric->QueryInterface( kISupportsIID, (void **)ppInterface);
}
}
}
NS_IF_RELEASE( pMail);
NS_IF_RELEASE( pGeneric);
return( rv);
}
if (!nsCRT::strcmp( pImportType, "addressbook")) {
// create the nsIImportMail interface and return it!
nsIImportAddressBooks * pAddress = nsnull;
nsIImportGeneric * pGeneric = nsnull;
rv = ImportAddressImpl::Create( &pAddress);
if (NS_SUCCEEDED( rv)) {
NS_WITH_SERVICE( nsIImportService, impSvc, kImportServiceCID, &rv);
if (NS_SUCCEEDED( rv)) {
rv = impSvc->CreateNewGenericAddressBooks( &pGeneric);
if (NS_SUCCEEDED( rv)) {
pGeneric->SetData( "addressInterface", pAddress);
rv = pGeneric->QueryInterface( kISupportsIID, (void **)ppInterface);
}
}
}
NS_IF_RELEASE( pAddress);
NS_IF_RELEASE( pGeneric);
return( rv);
}
if (!nsCRT::strcmp( pImportType, "settings")) {
nsIImportSettings *pSettings = nsnull;
rv = nsOutlookSettings::Create( &pSettings);
if (NS_SUCCEEDED( rv)) {
pSettings->QueryInterface( kISupportsIID, (void **)ppInterface);
}
NS_IF_RELEASE( pSettings);
return( rv);
}
return( NS_ERROR_NOT_AVAILABLE);
}
/////////////////////////////////////////////////////////////////////////////////
nsresult ImportMailImpl::Create(nsIImportMail** aImport)
{
NS_PRECONDITION(aImport != nsnull, "null ptr");
if (! aImport)
return NS_ERROR_NULL_POINTER;
*aImport = new ImportMailImpl();
if (! *aImport)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aImport);
return NS_OK;
}
ImportMailImpl::ImportMailImpl()
{
NS_INIT_REFCNT();
}
ImportMailImpl::~ImportMailImpl()
{
}
NS_IMPL_ISUPPORTS(ImportMailImpl, nsIImportMail::GetIID());
NS_IMETHODIMP ImportMailImpl::GetDefaultLocation( nsIFileSpec **ppLoc, PRBool *found, PRBool *userVerify)
{
NS_PRECONDITION(ppLoc != nsnull, "null ptr");
NS_PRECONDITION(found != nsnull, "null ptr");
NS_PRECONDITION(userVerify != nsnull, "null ptr");
if (!ppLoc || !found || !userVerify)
return NS_ERROR_NULL_POINTER;
// Bizarro, there really isn't a "default" location, the mail
// is in the MAPI store and we just open it via API
// We'll just use an "empty" file spec for now since we
// don't really care where the mail is.
nsresult rv;
nsIFileSpec * spec;
if (NS_FAILED( rv = NS_NewFileSpec( &spec)))
return( rv);
*found = PR_TRUE;
*ppLoc = spec;
*userVerify = PR_FALSE;
return( NS_OK);
}
NS_IMETHODIMP ImportMailImpl::FindMailboxes( nsIFileSpec *pLoc, nsISupportsArray **ppArray)
{
NS_PRECONDITION(pLoc != nsnull, "null ptr");
NS_PRECONDITION(ppArray != nsnull, "null ptr");
if (!pLoc || !ppArray)
return NS_ERROR_NULL_POINTER;
return( m_mail.GetMailFolders( ppArray));
}
void ImportMailImpl::AddLinebreak( nsString *pStream)
{
if (pStream)
pStream->Append( NS_LINEBREAK);
}
void ImportMailImpl::ReportSuccess( nsString& name, PRInt32 count, nsString *pStream)
{
if (!pStream)
return;
// load the success string
PRUnichar *pFmt = nsOutlookStringBundle::GetStringByID( OUTLOOKIMPORT_MAILBOX_SUCCESS);
PRUnichar *pText = nsTextFormater::smprintf( pFmt, name.GetUnicode(), count);
pStream->Append( pText);
nsTextFormater::smprintf_free( pText);
nsOutlookStringBundle::FreeString( pFmt);
AddLinebreak( pStream);
}
void ImportMailImpl::ReportError( PRInt32 errorNum, nsString& name, nsString *pStream)
{
if (!pStream)
return;
// load the error string
PRUnichar *pFmt = nsOutlookStringBundle::GetStringByID( errorNum);
PRUnichar *pText = nsTextFormater::smprintf( pFmt, name.GetUnicode());
pStream->Append( pText);
nsTextFormater::smprintf_free( pText);
nsOutlookStringBundle::FreeString( pFmt);
AddLinebreak( pStream);
}
void ImportMailImpl::SetLogs( nsString& success, nsString& error, PRUnichar **pError, PRUnichar **pSuccess)
{
if (pError)
*pError = error.ToNewUnicode();
if (pSuccess)
*pSuccess = success.ToNewUnicode();
}
NS_IMETHODIMP ImportMailImpl::ImportMailbox( nsIImportMailboxDescriptor *pSource,
nsIFileSpec *pDestination,
PRUnichar **pErrorLog,
PRUnichar **pSuccessLog,
PRBool *fatalError)
{
NS_PRECONDITION(pSource != nsnull, "null ptr");
NS_PRECONDITION(pDestination != nsnull, "null ptr");
NS_PRECONDITION(fatalError != nsnull, "null ptr");
nsString success;
nsString error;
if (!pSource || !pDestination || !fatalError) {
nsOutlookStringBundle::GetStringByID( OUTLOOKIMPORT_MAILBOX_BADPARAM, error);
if (fatalError)
*fatalError = PR_TRUE;
SetLogs( success, error, pErrorLog, pSuccessLog);
return NS_ERROR_NULL_POINTER;
}
PRBool abort = PR_FALSE;
nsString name;
PRUnichar * pName;
if (NS_SUCCEEDED( pSource->GetDisplayName( &pName))) {
name = pName;
nsCRT::free( pName);
}
PRUint32 mailSize = 0;
pSource->GetSize( &mailSize);
if (mailSize == 0) {
ReportSuccess( name, 0, &success);
SetLogs( success, error, pErrorLog, pSuccessLog);
return( NS_OK);
}
PRUint32 index = 0;
pSource->GetIdentifier( &index);
PRInt32 msgCount = 0;
nsresult rv = NS_OK;
rv = m_mail.ImportMailbox( &abort, (PRInt32)index, name.GetUnicode(), pDestination, &msgCount);
if (NS_SUCCEEDED( rv)) {
ReportSuccess( name, msgCount, &success);
}
else {
ReportError( OUTLOOKIMPORT_MAILBOX_CONVERTERROR, name, &error);
}
SetLogs( success, error, pErrorLog, pSuccessLog);
return( rv);
}
NS_IMETHODIMP ImportMailImpl::GetImportProgress( PRUint32 *pDoneSoFar)
{
NS_PRECONDITION(pDoneSoFar != nsnull, "null ptr");
if (! pDoneSoFar)
return NS_ERROR_NULL_POINTER;
// TLR: FIXME: Figure our how to update this from the import
// of the current mailbox.
*pDoneSoFar = 0;
return( NS_OK);
}
nsresult ImportAddressImpl::Create(nsIImportAddressBooks** aImport)
{
NS_PRECONDITION(aImport != nsnull, "null ptr");
if (! aImport)
return NS_ERROR_NULL_POINTER;
*aImport = new ImportAddressImpl();
if (! *aImport)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aImport);
return NS_OK;
}
ImportAddressImpl::ImportAddressImpl()
{
NS_INIT_REFCNT();
m_pWabImport = nsnull;
}
ImportAddressImpl::~ImportAddressImpl()
{
if (m_pWabImport)
m_pWabImport->Release();
}
NS_IMPL_ISUPPORTS(ImportAddressImpl, nsIImportAddressBooks::GetIID());
NS_IMETHODIMP ImportAddressImpl::GetAutoFind(PRUnichar **description, PRBool *_retval)
{
NS_PRECONDITION(description != nsnull, "null ptr");
NS_PRECONDITION(_retval != nsnull, "null ptr");
if (! description || !_retval)
return NS_ERROR_NULL_POINTER;
*_retval = PR_TRUE;
nsString str = "Outlook address book (windows address book)";
*description = str.ToNewUnicode();
return( NS_OK);
}
void ImportAddressImpl::GetOEInterface( void)
{
if (m_pWabImport)
return;
nsIImportModule * oeModule = nsnull;
nsresult rv = nsComponentManager::CreateInstance( "component://mozilla/import/import-oe", nsnull, nsIImportModule::GetIID(), (void **) &oeModule);
if (NS_SUCCEEDED( rv) && oeModule) {
nsIImportGeneric * generic = nsnull;
rv = oeModule->GetImportInterface( "addressbook", (nsISupports **) &generic);
if (NS_SUCCEEDED( rv) && generic) {
rv = generic->GetData( "addressInterface", (nsISupports **) &m_pWabImport);
generic->Release();
}
oeModule->Release();
}
}
NS_IMETHODIMP ImportAddressImpl::FindAddressBooks(nsIFileSpec *location, nsISupportsArray **_retval)
{
NS_PRECONDITION(_retval != nsnull, "null ptr");
if (!_retval)
return NS_ERROR_NULL_POINTER;
GetOEInterface();
if (!m_pWabImport) {
IMPORT_LOG0( "Outlook address book import failed, cannot load outlook express import module\n");
return( NS_ERROR_FAILURE);
}
return( m_pWabImport->FindAddressBooks( location, _retval));
}
NS_IMETHODIMP ImportAddressImpl::ImportAddressBook( nsIImportABDescriptor *source,
nsIAddrDatabase * destination,
nsISupports * fieldMap,
PRUnichar ** errorLog,
PRUnichar ** successLog,
PRBool * fatalError)
{
GetOEInterface();
if (!m_pWabImport) {
IMPORT_LOG0( "Outlook address book import failed, cannot load outlook express import module\n");
return( NS_ERROR_FAILURE);
}
return( m_pWabImport->ImportAddressBook( source, destination, fieldMap, errorLog, successLog, fatalError));
}
NS_IMETHODIMP ImportAddressImpl::GetImportProgress(PRUint32 *_retval)
{
GetOEInterface();
if (!m_pWabImport) {
IMPORT_LOG0( "Outlook address book import failed, cannot load outlook express import module\n");
return( NS_ERROR_FAILURE);
}
return( m_pWabImport->GetImportProgress( _retval));
}

View File

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsOutlookImport_h___
#define nsOutlookImport_h___
#include "nsIImportModule.h"
#include "nsCOMPtr.h"
#define NS_OUTLOOKIMPORT_CID \
{ /* 1DB469A0-8B00-11d3-A206-00A0CC26DA63 */ \
0x1db469a0, 0x8b00, 0x11d3, \
{0xa2, 0x6, 0x0, 0xa0, 0xcc, 0x26, 0xda, 0x63 }}
#define kOutlookSupportsString NS_IMPORT_MAIL_STR "," NS_IMPORT_ADDRESS_STR "," NS_IMPORT_SETTINGS_STR
class nsOutlookImport : public nsIImportModule
{
public:
nsOutlookImport();
virtual ~nsOutlookImport();
NS_DECL_ISUPPORTS
////////////////////////////////////////////////////////////////////////////////////////
// we suppport the nsIImportModule interface
////////////////////////////////////////////////////////////////////////////////////////
/* readonly attribute wstring name; */
NS_IMETHOD GetName(PRUnichar * *aName);
/* readonly attribute wstring description; */
NS_IMETHOD GetDescription(PRUnichar * *aDescription);
/* readonly attribute string supports; */
NS_IMETHOD GetSupports(char * *aSupports);
/* nsISupports GetImportInterface (in string importType); */
NS_IMETHOD GetImportInterface(const char *importType, nsISupports **_retval);
protected:
};
extern nsresult NS_NewOutlookImport(nsIImportModule** aImport);
#endif /* nsOutlookImport_h___ */

View File

@ -0,0 +1,476 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Outlook mail import
*/
#include "nsCOMPtr.h"
#include "nscore.h"
#include "nsIServiceManager.h"
#include "nsIImportService.h"
#include "nsIImportMailboxDescriptor.h"
#include "nsIImportMimeEncode.h"
#include "nsOutlookStringBundle.h"
#include "OutlookDebugLog.h"
#include "nsOutlookMail.h"
static NS_DEFINE_CID(kImportServiceCID, NS_IMPORTSERVICE_CID);
static NS_DEFINE_CID(kImportMimeEncodeCID, NS_IMPORTMIMEENCODE_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
nsOutlookMail::nsOutlookMail()
{
m_gotFolders = PR_FALSE;
m_haveMapi = CMapiApi::LoadMapi();
m_lpMdb = NULL;
}
nsOutlookMail::~nsOutlookMail()
{
CMapiApi::UnloadMapi();
}
nsresult nsOutlookMail::GetMailFolders( nsISupportsArray **pArray)
{
if (!m_haveMapi) {
IMPORT_LOG0( "GetMailFolders called before Mapi is initialized\n");
return( NS_ERROR_FAILURE);
}
nsresult rv = NS_NewISupportsArray( pArray);
if (NS_FAILED( rv)) {
IMPORT_LOG0( "FAILED to allocate the nsISupportsArray for the mail folder list\n");
return( rv);
}
NS_WITH_SERVICE( nsIImportService, impSvc, kImportServiceCID, &rv);
if (NS_FAILED( rv))
return( rv);
m_gotFolders = PR_TRUE;
m_storeList.ClearAll();
m_folderList.ClearAll();
m_mapi.Initialize();
m_mapi.LogOn();
m_mapi.IterateStores( m_storeList);
int i = 0;
CMapiFolder *pFolder;
if (m_storeList.GetSize() > 1) {
while ((pFolder = m_storeList.GetItem( i))) {
CMapiFolder *pItem = new CMapiFolder( pFolder);
pItem->SetDepth( 0);
m_folderList.AddItem( pItem);
if (!m_mapi.GetStoreFolders( pItem->GetCBEntryID(), pItem->GetEntryID(), m_folderList, 1)) {
IMPORT_LOG1( "GetStoreFolders for index %d failed.\n", i);
}
i++;
}
}
else {
if ((pFolder = m_storeList.GetItem( i))) {
if (!m_mapi.GetStoreFolders( pFolder->GetCBEntryID(), pFolder->GetEntryID(), m_folderList, 0)) {
IMPORT_LOG1( "GetStoreFolders for index %d failed.\n", i);
}
}
}
// Create the mailbox descriptors for the list of folders
nsIImportMailboxDescriptor * pID;
nsISupports * pInterface;
nsCString name;
PRUnichar * pChar;
for (i = 0; i < m_folderList.GetSize(); i++) {
pFolder = m_folderList.GetItem( i);
rv = impSvc->CreateNewMailboxDescriptor( &pID);
if (NS_SUCCEEDED( rv)) {
pID->SetDepth( pFolder->GetDepth());
pID->SetIdentifier( i);
pFolder->GetDisplayName( name);
pChar = name.ToNewUnicode();
pID->SetDisplayName( pChar);
nsCRT::free( pChar);
pID->SetSize( 1000);
rv = pID->QueryInterface( kISupportsIID, (void **) &pInterface);
(*pArray)->AppendElement( pInterface);
pInterface->Release();
pID->Release();
}
}
return( NS_OK);
}
void nsOutlookMail::OpenMessageStore( CMapiFolder *pNextFolder)
{
// Open the store specified
if (pNextFolder->IsStore()) {
if (!m_mapi.OpenStore( pNextFolder->GetCBEntryID(), pNextFolder->GetEntryID(), &m_lpMdb)) {
m_lpMdb = NULL;
IMPORT_LOG0( "CMapiApi::OpenStore failed\n");
}
return;
}
// Check to see if we should open the one and only store
if (!m_lpMdb) {
if (m_storeList.GetSize() == 1) {
CMapiFolder * pFolder = m_storeList.GetItem( 0);
if (pFolder) {
if (!m_mapi.OpenStore( pFolder->GetCBEntryID(), pFolder->GetEntryID(), &m_lpMdb)) {
m_lpMdb = NULL;
IMPORT_LOG0( "CMapiApi::OpenStore failed\n");
}
}
else {
IMPORT_LOG0( "Error retrieving the one & only message store\n");
}
}
else {
IMPORT_LOG0( "*** Error importing a folder without a valid message store\n");
}
}
}
nsresult nsOutlookMail::ImportMailbox( PRBool *pAbort, PRInt32 index, const PRUnichar *pName, nsIFileSpec *pDest, PRInt32 *pMsgCount)
{
if ((index < 0) || (index >= m_folderList.GetSize())) {
IMPORT_LOG0( "*** Bad mailbox identifier, unable to import\n");
*pAbort = PR_TRUE;
return( NS_ERROR_FAILURE);
}
if (pMsgCount)
*pMsgCount = 0;
CMapiFolder *pFolder = m_folderList.GetItem( index);
OpenMessageStore( pFolder);
if (!m_lpMdb) {
IMPORT_LOG1( "*** Unable to obtain mapi message store for mailbox: %S\n", pName);
return( NS_ERROR_FAILURE);
}
if (pFolder->IsStore())
return( NS_OK);
// now what?
CMapiFolderContents contents( m_lpMdb, pFolder->GetCBEntryID(), pFolder->GetEntryID());
BOOL done = FALSE;
ULONG cbEid;
LPENTRYID lpEid;
ULONG oType;
LPMESSAGE lpMsg;
int attachCount;
while (!done) {
if (pMsgCount)
(*pMsgCount)++;
if (!contents.GetNext( &cbEid, &lpEid, &oType, &done)) {
IMPORT_LOG1( "*** Error iterating mailbox: %S\n", pName);
return( NS_ERROR_FAILURE);
}
if (!done && (oType == MAPI_MESSAGE)) {
if (!m_mapi.OpenMdbEntry( m_lpMdb, cbEid, lpEid, (LPUNKNOWN *) &lpMsg)) {
IMPORT_LOG1( "*** Error opening messages in mailbox: %S\n", pName);
return( NS_ERROR_FAILURE);
}
CMapiMessage msg( lpMsg);
BOOL bResult = msg.FetchHeaders();
if (bResult)
bResult = msg.FetchBody();
attachCount = msg.CountAttachments();
if (!bResult) {
IMPORT_LOG1( "*** Error reading message from mailbox: %S\n", pName);
return( NS_ERROR_FAILURE);
}
BOOL needsTerminate = FALSE;
if (!WriteMessage( pDest, &msg, attachCount, &needsTerminate)) {
IMPORT_LOG0( "*** Error writing message\n");
*pAbort = PR_TRUE;
return( NS_ERROR_FAILURE);
}
if (attachCount) {
for (int i = 0; i < attachCount; i++) {
if (!msg.GetAttachmentInfo( i)) {
IMPORT_LOG1( "*** Error getting attachment info for #%d\n", i);
return( NS_ERROR_FAILURE);
}
if (!WriteAttachment( pDest, &msg)) {
IMPORT_LOG1( "** Error writing attachment #%d\n", i);
return( NS_ERROR_FAILURE);
}
}
}
if (needsTerminate) {
if (!WriteMimeBoundary( pDest, &msg, TRUE)) {
IMPORT_LOG0( "*** Error writing message mime boundary\n");
*pAbort = PR_TRUE;
return( NS_ERROR_FAILURE);
}
}
needsTerminate = FALSE;
}
}
return( NS_OK);
}
BOOL nsOutlookMail::WriteMessage( nsIFileSpec *pDest, CMapiMessage *pMsg, int& attachCount, BOOL *pTerminate)
{
BOOL bResult = TRUE;
const char *pData;
int len;
BOOL checkStart = FALSE;
*pTerminate = FALSE;
pData = pMsg->GetFromLine( len);
if (pData) {
bResult = WriteData( pDest, pData, len);
checkStart = TRUE;
}
pData = pMsg->GetHeaders( len);
if (pData && len) {
bResult = WriteWithoutFrom( pDest, pData, len, checkStart);
}
// Do we need to add any mime headers???
// Is the message multipart?
// If so, then we are OK, but need to make sure we add mime
// header info to the body of the message
// If not AND we have attachments, then we need to add mime headers.
BOOL needsMimeHeaders = pMsg->IsMultipart();
if (!needsMimeHeaders && attachCount) {
// if the message already has mime headers
// that aren't multipart then we are in trouble!
// in that case, ditch the attachments... alternatively, we could
// massage the headers and replace the existing mime headers
// with our own but I think this case is likely not to occur.
if (pMsg->HasContentHeader())
attachCount = 0;
else {
if (bResult)
bResult = WriteMimeMsgHeader( pDest, pMsg);
needsMimeHeaders = TRUE;
}
}
if (bResult)
bResult = WriteStr( pDest, "\x0D\x0A");
if (needsMimeHeaders) {
if (bResult)
bResult = WriteStr( pDest, "This is a MIME formatted message.\x0D\x0A");
if (bResult)
bResult = WriteStr( pDest, "\x0D\x0A");
if (bResult)
bResult = WriteMimeBoundary( pDest, pMsg, FALSE);
if (pMsg->BodyIsHtml()) {
if (bResult)
bResult = WriteStr( pDest, "Content-type: text/html\x0D\x0A");
}
else {
if (bResult)
bResult = WriteStr( pDest, "Content-type: text/plain\x0D\x0A");
}
if (bResult)
bResult = WriteStr( pDest, "\x0D\x0A");
}
pData = pMsg->GetBody( len);
if (pData && len) {
if (bResult)
bResult = WriteWithoutFrom( pDest, pData, len, TRUE);
if ((len < 2) || (pData[len - 1] != 0x0A) || (pData[len - 2] != 0x0D))
bResult = WriteStr( pDest, "\x0D\x0A");
}
*pTerminate = needsMimeHeaders;
return( bResult);
}
BOOL nsOutlookMail::WriteData( nsIFileSpec *pDest, const char *pData, PRInt32 len)
{
PRInt32 written;
nsresult rv = pDest->Write( pData, len, &written);
if (NS_FAILED( rv) || (written != len))
return( FALSE);
return( TRUE);
}
BOOL nsOutlookMail::WriteStr( nsIFileSpec *pDest, const char *pStr)
{
PRInt32 written;
PRInt32 len = nsCRT::strlen( pStr);
nsresult rv = pDest->Write( pStr, len, &written);
if (NS_FAILED( rv) || (written != len))
return( FALSE);
return( TRUE);
}
BOOL nsOutlookMail::WriteWithoutFrom( nsIFileSpec *pDest, const char *pData, int len, BOOL checkStart)
{
int wLen = 0;
const char * pChar = pData;
const char * pStart = pData;
if (!len)
return( TRUE);
if (!checkStart) {
pChar++;
wLen++;
len--;
}
else {
if ((len >= 5) && nsCRT::strncmp( pChar, "From ", 5)) {
if (!WriteStr( pDest, ">"))
return( FALSE);
}
}
while (len) {
if ((len >= 7) && nsCRT::strncmp( pChar, ("\x0D\x0A" "From "), 7)) {
wLen += 2;
len -= 2;
pChar += 2;
if (!WriteData( pDest, pStart, wLen))
return( FALSE);
if (!WriteStr( pDest, ">"))
return( FALSE);
wLen = 5;
pStart = pChar;
pChar += 5;
len -= 5;
}
else {
wLen++;
pChar++;
len--;
}
}
if (wLen) {
if (!WriteData( pDest, pStart, wLen))
return( FALSE);
}
return( TRUE);
}
BOOL nsOutlookMail::WriteMimeMsgHeader( nsIFileSpec *pDest, CMapiMessage *pMsg)
{
BOOL bResult = TRUE;
if (!pMsg->HasMimeVersion())
bResult = WriteStr( pDest, "MIME-Version: 1.0\x0D\x0A");
pMsg->GenerateBoundary();
if (bResult)
bResult = WriteStr( pDest, "Content-type: multipart/mixed; boundary=\"");
if (bResult)
bResult = WriteStr( pDest, pMsg->GetMimeBoundary());
if (bResult)
bResult = WriteStr( pDest, "\"\x0D\x0A");
return( bResult);
}
BOOL nsOutlookMail::WriteMimeBoundary( nsIFileSpec *pDest, CMapiMessage *pMsg, BOOL terminate)
{
BOOL bResult = WriteStr( pDest, "--");
if (bResult)
bResult = WriteStr( pDest, pMsg->GetMimeBoundary());
if (terminate && bResult)
bResult = WriteStr( pDest, "--");
if (bResult)
bResult = WriteStr( pDest, "\x0D\x0A");
return( bResult);
}
PRBool nsOutlookMail::WriteAttachment( nsIFileSpec *pDest, CMapiMessage *pMsg)
{
nsCOMPtr<nsIFileSpec> pSpec;
nsresult rv = NS_NewFileSpec( getter_AddRefs( pSpec));
if (NS_FAILED( rv) || !pSpec) {
IMPORT_LOG0( "*** Error creating file spec for attachment\n");
return( PR_FALSE);
}
if (pMsg->GetAttachFileLoc( pSpec)) {
PRBool isFile = PR_FALSE;
PRBool exists = PR_FALSE;
pSpec->Exists( &exists);
pSpec->IsFile( &isFile);
if (!exists || !isFile) {
IMPORT_LOG0( "Attachment file does not exist\n");
return( PR_TRUE);
}
}
else {
IMPORT_LOG0( "Attachment not processed, unable to obtain file\n");
return( PR_TRUE);
}
// Set up headers...
BOOL bResult = WriteMimeBoundary( pDest, pMsg, FALSE);
// Now set up the encoder object
if (bResult) {
nsCOMPtr<nsIImportMimeEncode> encoder;
rv = nsComponentManager::CreateInstance( kImportMimeEncodeCID, nsnull, nsIImportMimeEncode::GetIID(), getter_AddRefs( encoder));
if (NS_FAILED( rv)) {
IMPORT_LOG0( "*** Error creating mime encoder\n");
return( PR_FALSE);
}
encoder->Initialize( pSpec, pDest, pMsg->GetFileName(), pMsg->GetMimeType());
encoder->DoEncoding( &bResult);
}
return( bResult);
}

View File

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsOutlookMail_h___
#define nsOutlookMail_h___
#include "nsISupportsArray.h"
#include "nsIFileSpec.h"
#include "MapiApi.h"
#include "MapiMessage.h"
class nsOutlookMail {
public:
nsOutlookMail();
~nsOutlookMail();
nsresult GetMailFolders( nsISupportsArray **pArray);
nsresult ImportMailbox( PRBool *pAbort, PRInt32 index, const PRUnichar *pName, nsIFileSpec *pDest, PRInt32 *pMsgCount);
private:
void OpenMessageStore( CMapiFolder *pNextFolder);
BOOL WriteData( nsIFileSpec *pDest, const char *pData, PRInt32 len);
BOOL WriteMessage( nsIFileSpec *pDest, CMapiMessage *pMsg, int& attachCount, BOOL *pTerminate);
BOOL WriteStr( nsIFileSpec *pDest, const char *pStr);
BOOL WriteWithoutFrom( nsIFileSpec *pDest, const char * pData, int len, BOOL checkStart);
BOOL WriteMimeMsgHeader( nsIFileSpec *pDest, CMapiMessage *pMsg);
BOOL WriteMimeBoundary( nsIFileSpec *pDest, CMapiMessage *pMsg, BOOL terminate);
PRBool WriteAttachment( nsIFileSpec *pDest, CMapiMessage *pMsg);
private:
PRBool m_gotFolders;
PRBool m_haveMapi;
CMapiApi m_mapi;
CMapiFolderList m_folderList;
CMapiFolderList m_storeList;
LPMDB m_lpMdb;
};
#endif /* nsOutlookMail_h___ */

View File

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsOutlookRegUtil.h"
#include "OutlookDebugLog.h"
BYTE * nsOutlookRegUtil::GetValueBytes( HKEY hKey, const char *pValueName)
{
LONG err;
DWORD bufSz;
LPBYTE pBytes = NULL;
err = ::RegQueryValueEx( hKey, pValueName, NULL, NULL, NULL, &bufSz);
if (err == ERROR_SUCCESS) {
pBytes = new BYTE[bufSz];
err = ::RegQueryValueEx( hKey, pValueName, NULL, NULL, pBytes, &bufSz);
if (err != ERROR_SUCCESS) {
delete [] pBytes;
pBytes = NULL;
}
}
return( pBytes);
}
void nsOutlookRegUtil::FreeValueBytes( BYTE *pBytes)
{
if (pBytes)
delete [] pBytes;
}

View File

@ -0,0 +1,33 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsOutlookRegUtil_h___
#define nsOutlookRegUtil_h___
#include <windows.h>
class nsOutlookRegUtil
{
public:
static BYTE * GetValueBytes( HKEY hKey, const char *pValueName);
static void FreeValueBytes( BYTE *pBytes);
};
#endif /* nsOutlookRegUtil_h___ */

View File

@ -0,0 +1,494 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Outlook Express (Win32) settings
*/
#include "nsCOMPtr.h"
#include "nscore.h"
#include "nsOutlookImport.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIImportService.h"
#include "nsOutlookRegUtil.h"
#include "nsIMsgMailSession.h"
#include "nsIMsgAccountManager.h"
#include "nsIMsgAccount.h"
#include "nsIImportSettings.h"
#include "nsOutlookSettings.h"
#include "nsMsgBaseCID.h"
#include "nsMsgCompCID.h"
#include "nsISmtpService.h"
#include "nsISmtpServer.h"
#include "nsOutlookStringBundle.h"
#include "OutlookDebugLog.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID);
static NS_DEFINE_CID(kSmtpServiceCID, NS_SMTPSERVICE_CID);
class OutlookSettings {
public:
static HKEY FindAccountsKey( void);
static PRBool DoImport( nsIMsgAccount **ppAccount);
static PRBool DoIMAPServer( nsIMsgAccountManager *pMgr, HKEY hKey, char *pServerName, nsIMsgAccount **ppAccount);
static PRBool DoPOP3Server( nsIMsgAccountManager *pMgr, HKEY hKey, char *pServerName, nsIMsgAccount **ppAccount);
static void SetIdentities( nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, HKEY hKey);
static PRBool IdentityMatches( nsIMsgIdentity *pIdent, const char *pName, const char *pServer, const char *pEmail, const char *pReply, const char *pUserName);
static void SetSmtpServer( nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, char *pServer, char *pUser);
};
////////////////////////////////////////////////////////////////////////
nsresult nsOutlookSettings::Create(nsIImportSettings** aImport)
{
NS_PRECONDITION(aImport != nsnull, "null ptr");
if (! aImport)
return NS_ERROR_NULL_POINTER;
*aImport = new nsOutlookSettings();
if (! *aImport)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aImport);
return NS_OK;
}
nsOutlookSettings::nsOutlookSettings()
{
NS_INIT_REFCNT();
}
nsOutlookSettings::~nsOutlookSettings()
{
}
NS_IMPL_ISUPPORTS(nsOutlookSettings, nsIImportSettings::GetIID());
NS_IMETHODIMP nsOutlookSettings::AutoLocate(PRUnichar **description, nsIFileSpec **location, PRBool *_retval)
{
NS_PRECONDITION(description != nsnull, "null ptr");
NS_PRECONDITION(_retval != nsnull, "null ptr");
if (!description || !_retval)
return( NS_ERROR_NULL_POINTER);
*description = nsOutlookStringBundle::GetStringByID( OUTLOOKIMPORT_NAME);
*_retval = PR_FALSE;
if (location)
*location = nsnull;
// look for the registry key for the accounts
HKEY key = OutlookSettings::FindAccountsKey();
if (key != nsnull) {
*_retval = PR_TRUE;
::RegCloseKey( key);
}
return( NS_OK);
}
NS_IMETHODIMP nsOutlookSettings::SetLocation(nsIFileSpec *location)
{
return( NS_OK);
}
NS_IMETHODIMP nsOutlookSettings::Import(nsIMsgAccount **localMailAccount, PRBool *_retval)
{
NS_PRECONDITION( _retval != nsnull, "null ptr");
if (OutlookSettings::DoImport( localMailAccount)) {
*_retval = PR_TRUE;
IMPORT_LOG0( "Settings import appears successful\n");
}
else {
*_retval = PR_FALSE;
IMPORT_LOG0( "Settings import returned FALSE\n");
}
return( NS_OK);
}
HKEY OutlookSettings::FindAccountsKey( void)
{
HKEY sKey;
if (::RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\8.0\\Outlook\\OMI Account Manager\\Accounts", 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &sKey) == ERROR_SUCCESS) {
return( sKey);
}
return( nsnull);
}
PRBool OutlookSettings::DoImport( nsIMsgAccount **ppAccount)
{
HKEY hKey = FindAccountsKey();
if (hKey == nsnull) {
IMPORT_LOG0( "*** Error finding Outlook registry account keys\n");
return( PR_FALSE);
}
nsresult rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if (NS_FAILED(rv)) {
IMPORT_LOG0( "*** Failed to create a mail session!\n");
return( PR_FALSE);
}
nsCOMPtr<nsIMsgAccountManager> accMgr;
rv = mailSession->GetAccountManager( getter_AddRefs( accMgr));
if (NS_FAILED( rv)) {
IMPORT_LOG0( "*** Failed to get account manager\n");
return( PR_FALSE);
}
HKEY subKey;
nsCString defMailName;
// First let's get the default mail account key name
if (::RegOpenKeyEx( HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\8.0\\Outlook\\OMI Account Manager", 0, KEY_QUERY_VALUE, &subKey) == ERROR_SUCCESS) {
BYTE * pBytes = nsOutlookRegUtil::GetValueBytes( subKey, "Default Mail Account");
::RegCloseKey( subKey);
if (pBytes) {
defMailName = (const char *)pBytes;
nsOutlookRegUtil::FreeValueBytes( pBytes);
}
}
// Iterate the accounts looking for POP3 & IMAP accounts...
// Ignore LDAP & NNTP for now!
DWORD index = 0;
DWORD numChars;
TCHAR keyName[256];
FILETIME modTime;
LONG result = ERROR_SUCCESS;
BYTE * pBytes;
int popCount = 0;
int accounts = 0;
nsCString keyComp;
while (result == ERROR_SUCCESS) {
numChars = 256;
result = ::RegEnumKeyEx( hKey, index, keyName, &numChars, NULL, NULL, NULL, &modTime);
index++;
if (result == ERROR_SUCCESS) {
if (::RegOpenKeyEx( hKey, keyName, 0, KEY_QUERY_VALUE, &subKey) == ERROR_SUCCESS) {
// Get the values for this account.
IMPORT_LOG1( "Opened Outlook account: %s\n", (char *)keyName);
nsIMsgAccount *anAccount = nsnull;
pBytes = nsOutlookRegUtil::GetValueBytes( subKey, "IMAP Server");
if (pBytes) {
if (DoIMAPServer( accMgr, subKey, (char *)pBytes, &anAccount))
accounts++;
nsOutlookRegUtil::FreeValueBytes( pBytes);
}
pBytes = nsOutlookRegUtil::GetValueBytes( subKey, "POP3 Server");
if (pBytes) {
if (popCount == 0) {
if (DoPOP3Server( accMgr, subKey, (char *)pBytes, &anAccount)) {
popCount++;
accounts++;
if (ppAccount && anAccount) {
*ppAccount = anAccount;
NS_ADDREF( anAccount);
}
}
}
else {
if (DoPOP3Server( accMgr, subKey, (char *)pBytes, &anAccount)) {
popCount++;
accounts++;
// If we created a mail account, get rid of it since
// we have 2 POP accounts!
if (ppAccount && *ppAccount) {
NS_RELEASE( *ppAccount);
*ppAccount = nsnull;
}
}
}
nsOutlookRegUtil::FreeValueBytes( pBytes);
}
if (anAccount) {
// Is this the default account?
keyComp = keyName;
if (keyComp.Equals( defMailName)) {
accMgr->SetDefaultAccount( anAccount);
}
NS_RELEASE( anAccount);
}
::RegCloseKey( subKey);
}
}
}
return( accounts != 0);
}
PRBool OutlookSettings::DoIMAPServer( nsIMsgAccountManager *pMgr, HKEY hKey, char *pServerName, nsIMsgAccount **ppAccount)
{
if (ppAccount)
*ppAccount = nsnull;
BYTE *pBytes;
pBytes = nsOutlookRegUtil::GetValueBytes( hKey, "IMAP User Name");
if (!pBytes)
return( PR_FALSE);
PRBool result = PR_FALSE;
// I now have a user name/server name pair, find out if it already exists?
nsCOMPtr<nsIMsgIncomingServer> in;
nsresult rv = pMgr->FindServer( (const char *)pBytes, pServerName, "imap", getter_AddRefs( in));
if (NS_FAILED( rv) || (in == nsnull)) {
// Create the incoming server and an account for it?
rv = pMgr->CreateIncomingServer( "imap", getter_AddRefs( in));
if (NS_SUCCEEDED( rv) && in) {
rv = in->SetType( "imap");
rv = in->SetHostName( pServerName);
rv = in->SetUsername( (char *)pBytes);
IMPORT_LOG2( "Created IMAP server named: %s, userName: %s\n", pServerName, (char *)pBytes);
BYTE *pAccName = nsOutlookRegUtil::GetValueBytes( hKey, "Account Name");
nsString prettyName;
if (pAccName) {
prettyName = (const char *)pAccName;
nsOutlookRegUtil::FreeValueBytes( pAccName);
}
else
prettyName = (const char *)pServerName;
PRUnichar *pretty = prettyName.ToNewUnicode();
IMPORT_LOG1( "\tSet pretty name to: %S\n", pretty);
rv = in->SetPrettyName( pretty);
nsCRT::free( pretty);
// We have a server, create an account.
nsCOMPtr<nsIMsgAccount> account;
rv = pMgr->CreateAccount( getter_AddRefs( account));
if (NS_SUCCEEDED( rv) && account) {
rv = account->SetIncomingServer( in);
IMPORT_LOG0( "Created an account and set the IMAP server as the incoming server\n");
// Fiddle with the identities
SetIdentities( pMgr, account, hKey);
result = PR_TRUE;
if (ppAccount)
account->QueryInterface( nsIMsgAccount::GetIID(), (void **)ppAccount);
}
}
}
else
result = PR_TRUE;
nsOutlookRegUtil::FreeValueBytes( pBytes);
return( result);
}
PRBool OutlookSettings::DoPOP3Server( nsIMsgAccountManager *pMgr, HKEY hKey, char *pServerName, nsIMsgAccount **ppAccount)
{
if (ppAccount)
*ppAccount = nsnull;
BYTE *pBytes;
pBytes = nsOutlookRegUtil::GetValueBytes( hKey, "POP3 User Name");
if (!pBytes)
return( PR_FALSE);
PRBool result = PR_FALSE;
// I now have a user name/server name pair, find out if it already exists?
nsCOMPtr<nsIMsgIncomingServer> in;
nsresult rv = pMgr->FindServer( (const char *)pBytes, pServerName, "pop3", getter_AddRefs( in));
if (NS_FAILED( rv) || (in == nsnull)) {
// Create the incoming server and an account for it?
rv = pMgr->CreateIncomingServer( "pop3", getter_AddRefs( in));
if (NS_SUCCEEDED( rv) && in) {
rv = in->SetType( "pop3");
rv = in->SetHostName( pServerName);
rv = in->SetUsername( (char *)pBytes);
IMPORT_LOG2( "Created POP3 server named: %s, userName: %s\n", pServerName, (char *)pBytes);
BYTE *pAccName = nsOutlookRegUtil::GetValueBytes( hKey, "Account Name");
nsString prettyName;
if (pAccName) {
prettyName = (const char *)pAccName;
nsOutlookRegUtil::FreeValueBytes( pAccName);
}
else
prettyName = (const char *)pServerName;
PRUnichar *pretty = prettyName.ToNewUnicode();
IMPORT_LOG1( "\tSet pretty name to: %S\n", pretty);
rv = in->SetPrettyName( pretty);
nsCRT::free( pretty);
// We have a server, create an account.
nsCOMPtr<nsIMsgAccount> account;
rv = pMgr->CreateAccount( getter_AddRefs( account));
if (NS_SUCCEEDED( rv) && account) {
rv = account->SetIncomingServer( in);
IMPORT_LOG0( "Created a new account and set the incoming server to the POP3 server.\n");
// Fiddle with the identities
SetIdentities( pMgr, account, hKey);
result = PR_TRUE;
if (ppAccount)
account->QueryInterface( nsIMsgAccount::GetIID(), (void **)ppAccount);
}
}
}
else
result = PR_TRUE;
nsOutlookRegUtil::FreeValueBytes( pBytes);
return( result);
}
PRBool OutlookSettings::IdentityMatches( nsIMsgIdentity *pIdent, const char *pName, const char *pServer, const char *pEmail, const char *pReply, const char *pUserName)
{
if (!pIdent)
return( PR_FALSE);
char * pIName = nsnull;
char * pIEmail = nsnull;
char * pIReply = nsnull;
PRBool result = PR_TRUE;
// The test here is:
// If the smtp host is the same
// and the email address is the same (if it is supplied)
// and the reply to address is the same (if it is supplied)
// then we match regardless of the full name.
nsresult rv = pIdent->GetFullName( &pIName);
rv = pIdent->GetEmail( &pIEmail);
rv = pIdent->GetReplyTo( &pIReply);
// for now, if it's the same server and reply to and email then it matches
if (pReply) {
if (!pIReply || nsCRT::strcasecmp( pReply, pIReply))
result = PR_FALSE;
}
if (pEmail) {
if (!pIEmail || nsCRT::strcasecmp( pEmail, pIEmail))
result = PR_FALSE;
}
nsCRT::free( pIName);
nsCRT::free( pIEmail);
nsCRT::free( pIReply);
return( result);
}
void OutlookSettings::SetIdentities( nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, HKEY hKey)
{
// Get the relevant information for an identity
char *pName = (char *)nsOutlookRegUtil::GetValueBytes( hKey, "SMTP Display Name");
char *pServer = (char *)nsOutlookRegUtil::GetValueBytes( hKey, "SMTP Server");
char *pEmail = (char *)nsOutlookRegUtil::GetValueBytes( hKey, "SMTP Email Address");
char *pReply = (char *)nsOutlookRegUtil::GetValueBytes( hKey, "SMTP Reply To Email Address");
char *pUserName = (char *)nsOutlookRegUtil::GetValueBytes( hKey, "SMTP User Name");
nsresult rv;
if (pEmail && pName && pServer) {
// The default identity, nor any other identities matched,
// create a new one and add it to the account.
nsCOMPtr<nsIMsgIdentity> id;
rv = pMgr->CreateIdentity( getter_AddRefs( id));
if (id) {
id->SetFullName( pName);
id->SetIdentityName( pName);
id->SetEmail( pEmail);
if (pReply)
id->SetReplyTo( pReply);
pAcc->AddIdentity( id);
IMPORT_LOG0( "Created identity and added to the account\n");
IMPORT_LOG1( "\tname: %s\n", pName);
IMPORT_LOG1( "\temail: %s\n", pEmail);
}
}
SetSmtpServer( pMgr, pAcc, pServer, pUserName);
nsOutlookRegUtil::FreeValueBytes( (BYTE *)pName);
nsOutlookRegUtil::FreeValueBytes( (BYTE *)pServer);
nsOutlookRegUtil::FreeValueBytes( (BYTE *)pEmail);
nsOutlookRegUtil::FreeValueBytes( (BYTE *)pReply);
nsOutlookRegUtil::FreeValueBytes( (BYTE *)pUserName);
}
void OutlookSettings::SetSmtpServer( nsIMsgAccountManager *pMgr, nsIMsgAccount *pAcc, char *pServer, char *pUser)
{
nsresult rv;
NS_WITH_SERVICE(nsISmtpService, smtpService, kSmtpServiceCID, &rv);
if (NS_SUCCEEDED(rv) && smtpService) {
nsCOMPtr<nsISmtpServer> foundServer;
rv = smtpService->FindServer( pServer, getter_AddRefs( foundServer));
if (NS_SUCCEEDED( rv) && foundServer) {
IMPORT_LOG1( "SMTP server already exists: %s\n", pServer);
return;
}
nsCOMPtr<nsISmtpServer> smtpServer;
rv = smtpService->CreateSmtpServer( getter_AddRefs( smtpServer));
if (NS_SUCCEEDED( rv) && smtpServer) {
smtpServer->SetHostname( pServer);
if (pUser)
smtpServer->SetUsername( pUser);
IMPORT_LOG1( "Created new SMTP server: %s\n", pServer);
}
}
}

View File

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsOutlookSettings_h___
#define nsOutlookSettings_h___
#include "nsIImportSettings.h"
class nsOutlookSettings : public nsIImportSettings {
public:
nsOutlookSettings();
virtual ~nsOutlookSettings();
static nsresult Create(nsIImportSettings** aImport);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIImportSettings interface
NS_DECL_NSIIMPORTSETTINGS
private:
};
#endif /* nsOutlookSettings_h___ */

View File

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "prprf.h"
#include "prmem.h"
#include "nsCOMPtr.h"
#include "nsIStringBundle.h"
#include "nsOutlookStringBundle.h"
#include "nsIServiceManager.h"
#include "nsIURI.h"
/* This is the next generation string retrieval call */
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
#define OUTLOOK_MSGS_URL "chrome://messenger/locale/outlookImportMsgs.properties"
nsIStringBundle *nsOutlookStringBundle::GetStringBundle( void)
{
nsresult rv;
char* propertyURL = OUTLOOK_MSGS_URL;
nsIStringBundle* sBundle = nsnull;
NS_WITH_SERVICE(nsIStringBundleService, sBundleService, kStringBundleServiceCID, &rv);
if (NS_SUCCEEDED(rv) && (nsnull != sBundleService)) {
nsILocale * locale = nsnull;
rv = sBundleService->CreateBundle(propertyURL, locale, &sBundle);
}
return( sBundle);
}
void nsOutlookStringBundle::GetStringByID( PRInt32 stringID, nsString& result, nsIStringBundle *pBundle)
{
PRUnichar *ptrv = GetStringByID( stringID, pBundle);
result = ptrv;
FreeString( ptrv);
}
PRUnichar *nsOutlookStringBundle::GetStringByID(PRInt32 stringID, nsIStringBundle *pBundle)
{
PRBool mine = PR_FALSE;
if (!pBundle) {
mine = PR_TRUE;
pBundle = GetStringBundle();
}
if (pBundle) {
PRUnichar *ptrv = nsnull;
nsresult rv = pBundle->GetStringFromID(stringID, &ptrv);
if (mine) {
NS_RELEASE(pBundle);
}
if (NS_SUCCEEDED( rv) && ptrv)
return( ptrv);
}
nsString resultString( "[StringID ");
resultString.Append(stringID, 10);
resultString += "?]";
return( resultString.ToNewUnicode());
}

View File

@ -0,0 +1,45 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef _nsOutlookStringBundle_H__
#define _nsOutlookStringBundle_H__
#include "nsCRT.h"
#include "nsString.h"
class nsIStringBundle;
class nsOutlookStringBundle {
public:
static PRUnichar * GetStringByID(PRInt32 stringID, nsIStringBundle *pBundle = nsnull);
static void GetStringByID(PRInt32 stringID, nsString& result, nsIStringBundle *pBundle = nsnull);
// GetStringBundle creates a new one every time!
static nsIStringBundle * GetStringBundle( void);
static void FreeString( PRUnichar *pStr) { nsCRT::free( pStr);}
};
#define OUTLOOKIMPORT_NAME 2000
#define OUTLOOKIMPORT_DESCRIPTION 2001
#define OUTLOOKIMPORT_MAILBOX_SUCCESS 2002
#define OUTLOOKIMPORT_MAILBOX_BADPARAM 2003
#define OUTLOOKIMPORT_MAILBOX_CONVERTERROR 2004
#endif /* _nsOutlookStringBundle_H__ */

View File

@ -26,6 +26,7 @@ XPIDLSRCS= .\nsIImportService.idl \
.\nsIImportAddressBooks.idl \
.\nsIImportABDescriptor.idl \
.\nsIImportSettings.idl \
.\nsIImportMimeEncode.idl \
$(NULL)
MODULE= import

View File

@ -0,0 +1,55 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Encodes a file from disk into an output stream including properly
encoded mime headers.
*/
#include "nsISupports.idl"
interface nsIFileSpec;
[scriptable, uuid(455ca0a0-8de2-11d3-a206-00a0cc26da63)]
interface nsIImportMimeEncode : nsISupports
{
void EncodeFile( in nsIFileSpec inFile, in nsIFileSpec outFile, [const] in string fileName, [const] in string mimeType);
boolean DoWork( out boolean done);
long NumBytesProcessed();
boolean DoEncoding();
void Initialize( in nsIFileSpec inFile, in nsIFileSpec outFile, [const] in string fileName, [const] in string mimeType);
};
%{ C++
#define NS_IMPORTMIMEENCODE_CID \
{ /* e4a1a340-8de2-11d3-a206-00a0cc26da63 */ \
0xe4a1a340, \
0x8de2, \
0x11d3, \
{0xa2, 0x06, 0x00, 0xa0, 0xcc, 0x26, 0xda, 0x63} \
}
%}

View File

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "ImportCharSet.h"
char ImportCharSet::m_upperCaseMap[256];
char ImportCharSet::m_Ascii[256];
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['('] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[')'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii['<'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii['>'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii['@'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[','] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[';'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[':'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii['\\'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii['"'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii['.'] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii['['] |= ImportCharSet::c822SpecialChar;
ImportCharSet::m_Ascii[']'] |= ImportCharSet::c822SpecialChar;
}

View File

@ -0,0 +1,188 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#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 PRBool IsUSAscii( PRUint8 ch) { return( ((ch & (PRUint8)0x80) == 0));}
inline static PRBool Is822CtlChar( PRUint8 ch) { return( (ch < 32));}
inline static PRBool Is822SpecialChar( PRUint8 ch) { return( (m_Ascii[ch] & c822SpecialChar) == c822SpecialChar);}
inline static PRBool IsWhiteSpace( PRUint8 ch) { return( (m_Ascii[ch] & cWhiteSpaceChar) == cWhiteSpaceChar); }
inline static PRBool IsAlphaNum( PRUint8 ch) { return( (m_Ascii[ch] & cAlphaNumChar) == cAlphaNumChar); }
inline static PRBool IsDigit( PRUint8 ch) { return( (m_Ascii[ch] & cDigitChar) == cDigitChar); }
inline static PRUint8 ToLower( PRUint8 ch) { if ((m_Ascii[ch] & cAlphaChar) == cAlphaChar) { return( cLowerAChar + (m_upperCaseMap[ch] - cUpperAChar)); } else return( ch); }
inline static long AsciiToLong( const PRUint8 * pChar, PRUint32 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( PRUint8 byte, PRUint8 * pHex) {
PRUint8 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( PRUint32 type, PRUint8 * pStr) {
ByteToHex( (PRUint8) (type >> 24), pStr);
pStr += 2;
ByteToHex( (PRUint8) ((type >> 16) & 0x0FF), pStr);
pStr += 2;
ByteToHex( (PRUint8) ((type >> 8) & 0x0FF), pStr);
pStr += 2;
ByteToHex( (PRUint8) (type & 0x0FF), pStr);
}
inline static void SkipWhiteSpace( const PRUint8 * & pChar, PRUint32 & pos, PRUint32 max) {
while ((pos < max) && (IsWhiteSpace( *pChar))) {
pos++; pChar++;
}
}
inline static void SkipSpaceTab( const PRUint8 * & pChar, PRUint32& pos, PRUint32 max) {
while ((pos < max) && ((*pChar == (PRUint8)cSpaceChar) || (*pChar == (PRUint8)cTabChar))) {
pos++; pChar++;
}
}
inline static void SkipTilSpaceTab( const PRUint8 * & pChar, PRUint32& pos, PRUint32 max) {
while ((pos < max) && (*pChar != (PRUint8)cSpaceChar) && (*pChar != (PRUint8)cTabChar)) {
pos++;
pChar++;
}
}
inline static PRBool StrNICmp( const PRUint8 * pChar, const PRUint8 * pSrc, PRUint32 len) {
while (len && (m_upperCaseMap[*pChar] == m_upperCaseMap[*pSrc])) {
pChar++; pSrc++; len--;
}
return( len == 0);
}
inline static PRBool StrNCmp( const PRUint8 * pChar, const PRUint8 *pSrc, PRUint32 len) {
while (len && (*pChar == *pSrc)) {
pChar++; pSrc++; len--;
}
return( len == 0);
}
inline static int FindChar( const PRUint8 * pChar, PRUint8 ch, PRUint32 max) {
PRUint32 pos = 0;
while ((pos < max) && (*pChar != ch)) {
pos++; pChar++;
}
if (pos < max)
return( (int) pos);
else
return( -1);
}
inline static PRBool NextChar( const PRUint8 * & pChar, PRUint8 ch, PRUint32& pos, PRUint32 max) {
if ((pos < max) && (*pChar == ch)) {
pos++;
pChar++;
return( PR_TRUE);
}
return( PR_FALSE);
}
inline static PRInt32 strcmp( const char * pS1, const char * pS2) {
while (*pS1 && *pS2 && (*pS1 == *pS2)) {
pS1++;
pS2++;
}
return( *pS1 - *pS2);
}
inline static PRInt32 stricmp( const char * pS1, const char * pS2) {
while (*pS1 && *pS2 && (m_upperCaseMap[*pS1] == m_upperCaseMap[*pS2])) {
pS1++;
pS2++;
}
return( m_upperCaseMap[*pS1] - m_upperCaseMap[*pS2]);
}
};
#endif /* ImportCharSet_h__ */

View File

@ -0,0 +1,309 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsString.h"
#include "nsCRT.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 = PR_FALSE;
m_pos = 0;
m_pBuf = nsnull;
m_bufSz = 0;
m_pFile = nsnull;
m_pTrans = nsnull;
m_pTransOut = nsnull;
m_pTransBuf = nsnull;
}
ImportOutFile::ImportOutFile( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz)
{
m_pTransBuf = nsnull;
m_pTransOut = nsnull;
m_pTrans = nsnull;
m_ownsFileAndBuffer = PR_FALSE;
InitOutFile( pSpec, pBuf, sz);
}
ImportOutFile::~ImportOutFile()
{
if (m_ownsFileAndBuffer) {
Flush();
if (m_pBuf)
delete [] m_pBuf;
}
NS_IF_RELEASE( m_pFile);
if (m_pTrans)
delete m_pTrans;
if (m_pTransOut)
delete m_pTransOut;
if (m_pTransBuf)
delete m_pTransBuf;
}
PRBool ImportOutFile::Set8bitTranslator( nsImportTranslator *pTrans)
{
if (!Flush())
return( PR_FALSE);
m_engaged = PR_FALSE;
m_pTrans = pTrans;
m_supports8to7 = pTrans->Supports8bitEncoding();
return( PR_TRUE);
}
PRBool ImportOutFile::End8bitTranslation( PRBool *pEngaged, nsCString& useCharset, nsCString& encoding)
{
if (!m_pTrans)
return( PR_FALSE);
PRBool 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 = nsnull;
if (m_pTransOut)
delete m_pTransOut;
m_pTransOut = nsnull;
if (m_pTransBuf)
delete m_pTransBuf;
m_pTransBuf = nsnull;
return( bResult);
}
PRBool ImportOutFile::InitOutFile( nsIFileSpec *pSpec, PRUint32 bufSz)
{
if (!bufSz)
bufSz = 32 * 1024;
if (!m_pBuf) {
m_pBuf = new PRUint8[ bufSz];
}
// m_fH = UFile::CreateFile( oFile, kMacNoCreator, kMacTextFile);
PRBool open = PR_FALSE;
nsresult rv = pSpec->IsStreamOpen( &open);
if (NS_FAILED( rv) || !open) {
rv = pSpec->OpenStreamForWriting();
if (NS_FAILED( rv)) {
IMPORT_LOG0( "Couldn't create outfile\n");
delete [] m_pBuf;
m_pBuf = nsnull;
return( PR_FALSE);
}
}
m_pFile = pSpec;
NS_ADDREF( m_pFile);
m_ownsFileAndBuffer = PR_TRUE;
m_pos = 0;
m_bufSz = bufSz;
return( PR_TRUE);
}
void ImportOutFile::InitOutFile( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz)
{
m_ownsFileAndBuffer = PR_FALSE;
m_pFile = pSpec;
NS_IF_ADDREF( m_pFile);
m_pBuf = pBuf;
m_bufSz = sz;
m_pos = 0;
}
PRBool ImportOutFile::Flush( void)
{
if (!m_pos)
return( PR_TRUE);
PRUint32 transLen;
PRBool duddleyDoWrite = PR_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( PR_FALSE);
if (!m_pTransOut->Flush())
return( PR_FALSE);
// now update our buffer...
if (transLen < m_pos) {
nsCRT::memcpy( m_pBuf, m_pBuf + transLen, m_pos - transLen);
}
m_pos -= transLen;
}
else if (m_engaged) {
// does not actually support translation!
duddleyDoWrite = PR_TRUE;
}
else {
// should we engage?
PRUint8 * pChar = m_pBuf;
PRUint32 len = m_pos;
while (len) {
if (!ImportCharSet::IsUSAscii( *pChar))
break;
pChar++;
len--;
}
if (len) {
m_engaged = PR_TRUE;
if (m_supports8to7) {
// allocate our translation output buffer and file...
m_pTransBuf = new PRUint8[m_bufSz];
m_pTransOut = new ImportOutFile( m_pFile, m_pTransBuf, m_bufSz);
return( Flush());
}
else
duddleyDoWrite = PR_TRUE;
}
else {
duddleyDoWrite = PR_TRUE;
}
}
}
else
duddleyDoWrite = PR_TRUE;
if (duddleyDoWrite) {
PRInt32 written = 0;
nsresult rv = m_pFile->Write( (const char *)m_pBuf, (PRInt32)m_pos, &written);
if (NS_FAILED( rv) || ((PRUint32)written != m_pos))
return( PR_FALSE);
m_pos = 0;
}
return( PR_TRUE);
}
PRBool ImportOutFile::WriteU8NullTerm( const PRUint8 * pSrc, PRBool includeNull)
{
while (*pSrc) {
if (m_pos >= m_bufSz) {
if (!Flush())
return( PR_FALSE);
}
*(m_pBuf + m_pos) = *pSrc;
m_pos++;
pSrc++;
}
if (includeNull) {
if (m_pos >= m_bufSz) {
if (!Flush())
return( PR_FALSE);
}
*(m_pBuf + m_pos) = 0;
m_pos++;
}
return( PR_TRUE);
}
PRBool ImportOutFile::SetMarker( int markerID)
{
if (!Flush()) {
return( PR_FALSE);
}
if (markerID < kMaxMarkers) {
PRInt32 pos = 0;
nsresult rv;
if (m_pFile) {
rv = m_pFile->Tell( &pos);
if (NS_FAILED( rv)) {
IMPORT_LOG0( "*** Error, Tell failed on output stream\n");
return( PR_FALSE);
}
}
m_markers[markerID] = (PRUint32)pos + m_pos;
}
return( PR_TRUE);
}
void ImportOutFile::ClearMarker( int markerID)
{
if (markerID < kMaxMarkers)
m_markers[markerID] = 0;
}
PRBool ImportOutFile::WriteStrAtMarker( int markerID, const char *pStr)
{
if (markerID >= kMaxMarkers)
return( PR_FALSE);
if (!Flush())
return( PR_FALSE);
nsresult rv;
PRInt32 pos;
rv = m_pFile->Tell( &pos);
if (NS_FAILED( rv))
return( PR_FALSE);
rv = m_pFile->Seek( (PRInt32) m_markers[markerID]);
if (NS_FAILED( rv))
return( PR_FALSE);
PRInt32 written;
rv = m_pFile->Write( pStr, nsCRT::strlen( pStr), &written);
if (NS_FAILED( rv))
return( PR_FALSE);
rv = m_pFile->Seek( pos);
if (NS_FAILED( rv))
return( PR_FALSE);
return( PR_TRUE);
}

View File

@ -0,0 +1,105 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef ImportOutFile_h___
#define ImportOutFile_h___
#include "nsImportTranslator.h"
#include "nsIFileSpec.h"
#define kMaxMarkers 10
class ImportOutFile;
class ImportOutFile {
public:
ImportOutFile();
ImportOutFile( nsIFileSpec *pFile, PRUint8 * pBuf, PRUint32 sz);
~ImportOutFile();
PRBool InitOutFile( nsIFileSpec *pFile, PRUint32 bufSz = 4096);
void InitOutFile( nsIFileSpec *pFile, PRUint8 * pBuf, PRUint32 sz);
inline PRBool WriteData( const PRUint8 * pSrc, PRUint32 len);
inline PRBool WriteByte( PRUint8 byte);
PRBool WriteStr( const char *pStr) {return( WriteU8NullTerm( (const PRUint8 *) pStr, PR_FALSE)); }
PRBool WriteU8NullTerm( const PRUint8 * pSrc, PRBool includeNull);
PRBool WriteEol( void) { return( WriteStr( "\x0D\x0A")); }
PRBool Done( void) {return( Flush());}
// Marker support
PRBool SetMarker( int markerID);
void ClearMarker( int markerID);
PRBool WriteStrAtMarker( int markerID, const char *pStr);
// 8-bit to 7-bit translation
PRBool Set8bitTranslator( nsImportTranslator *pTrans);
PRBool End8bitTranslation( PRBool *pEngaged, nsCString& useCharset, nsCString& encoding);
protected:
PRBool Flush( void);
protected:
nsIFileSpec * m_pFile;
PRUint8 * m_pBuf;
PRUint32 m_bufSz;
PRUint32 m_pos;
PRBool m_ownsFileAndBuffer;
// markers
PRUint32 m_markers[kMaxMarkers];
// 8 bit to 7 bit translations
nsImportTranslator * m_pTrans;
PRBool m_engaged;
PRBool m_supports8to7;
ImportOutFile * m_pTransOut;
PRUint8 * m_pTransBuf;
};
inline PRBool ImportOutFile::WriteData( const PRUint8 * pSrc, PRUint32 len) {
while ((len + m_pos) > m_bufSz) {
if ((m_bufSz - m_pos)) {
nsCRT::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( PR_FALSE);
}
if (len) {
nsCRT::memcpy( m_pBuf + m_pos, pSrc, len);
m_pos += len;
}
return( PR_TRUE);
}
inline PRBool ImportOutFile::WriteByte( PRUint8 byte) {
if (m_pos == m_bufSz) {
if (!Flush())
return( PR_FALSE);
}
*(m_pBuf + m_pos) = byte;
m_pos++;
return( PR_TRUE);
}
#endif /* ImportOutFile_h__ */

View File

@ -0,0 +1,118 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "ImportTranslate.h"
int ImportTranslate::m_useTranslator = -1;
PRBool ImportTranslate::ConvertString( const nsCString& inStr, nsCString& outStr, PRBool mimeHeader)
{
if (inStr.IsEmpty()) {
outStr = inStr;
return( PR_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();
PRUint8 * 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 PRUint8[pTrans->GetMaxBufferSize( outStr.Length())];
pTrans->ConvertBuffer( (const PRUint8 *)((const char *)outStr), outStr.Length(), pBuf);
delete pTrans;
outStr.Truncate();
if (mimeHeader) {
outStr = set;
outStr += "'";
outStr += lang;
outStr += "'";
}
outStr += (const char *)pBuf;
delete [] pBuf;
return( PR_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( nsnull);
}

View File

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef ImportTranslate_h___
#define ImportTranslate_h___
#include "nsString.h"
#include "nsImportTranslator.h"
class ImportTranslate {
public:
static PRBool ConvertString( const nsCString& inStr, nsCString& outStr, PRBool mimeHeader);
static nsImportTranslator *GetTranslator( void);
static nsImportTranslator *GetMatchingTranslator( const char *pCharSet);
protected:
static int m_useTranslator;
};
#endif /* ImportTranslate_h__ */

View File

@ -31,6 +31,13 @@ CPP_OBJS=\
.\$(OBJDIR)\nsImportABDescriptor.obj \
.\$(OBJDIR)\nsImportAddressBooks.obj \
.\$(OBJDIR)\nsImportStringBundle.obj \
.\$(OBJDIR)\ImportTranslate.obj \
.\$(OBJDIR)\nsImportTranslator.obj \
.\$(OBJDIR)\ImportCharSet.obj \
.\$(OBJDIR)\ImportOutFile.obj \
.\$(OBJDIR)\nsImportScanFile.obj \
.\$(OBJDIR)\nsImportEncodeScan.obj \
.\$(OBJDIR)\nsImportMimeEncode.obj \
$(NULL)
LLIBS=\

View File

@ -0,0 +1,390 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsCRT.h"
#include "nsImportEncodeScan.h"
#define kBeginAppleSingle 0
#define kBeginDataFork 1
#define kBeginResourceFork 2
#define kAddEntries 3
#define kScanningDataFork 4
#define kScanningRsrcFork 5
#define kDoneWithFile 6
PRUint32 gAppleSingleHeader[6] = {0x00051600, 0x00020000, 0, 0, 0, 0};
#define kAppleSingleHeaderSize (6 * sizeof( PRUint32))
#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_pFile = nsnull;
m_isAppleSingle = PR_FALSE;
m_encodeScanState = 0;
m_resourceForkSize = 0;
m_dataForkSize = 0;
m_pInputFile = nsnull;
}
nsImportEncodeScan::~nsImportEncodeScan()
{
NS_IF_RELEASE( m_pInputFile);
}
PRBool nsImportEncodeScan::InitEncodeScan( PRBool appleSingleEncode, nsIFileSpec *fileLoc, const char *pName, PRUint8 * pBuf, PRUint32 sz)
{
CleanUpEncodeScan();
m_isAppleSingle = appleSingleEncode;
m_encodeScanState = kBeginAppleSingle;
m_pInputFile = fileLoc;
NS_IF_ADDREF( m_pInputFile);
m_useFileName = pName;
m_pBuf = pBuf;
m_bufSz = sz;
if (!m_isAppleSingle) {
PRBool open = PR_FALSE;
nsresult rv = m_pInputFile->IsStreamOpen( &open);
if (NS_FAILED( rv) || !open) {
rv = m_pInputFile->OpenStreamForReading();
if (NS_FAILED( rv))
return( PR_FALSE);
}
InitScan( m_pInputFile, 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( PR_TRUE);
}
void nsImportEncodeScan::CleanUpEncodeScan( void)
{
NS_IF_RELEASE( m_pInputFile);
m_pInputFile = nsnull;
}
// 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
}
PRBool 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( PR_TRUE);
}
PRBool nsImportEncodeScan::Scan( PRBool *pDone)
{
nsresult rv;
*pDone = PR_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 = PR_FALSE;
m_pos = 0;
nsCRT::memcpy( m_pBuf, gAppleSingleHeader, kAppleSingleHeaderSize);
m_bytesInBuf = kAppleSingleHeaderSize;
int numEntries = 5;
if (m_dataForkSize)
numEntries++;
if (m_resourceForkSize)
numEntries++;
nsCRT::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( PR_TRUE);
}
// Initialize the scan of the data fork...
PRBool open = PR_FALSE;
rv = m_pInputFile->IsStreamOpen( &open);
if (!open)
rv = m_pInputFile->OpenStreamForReading();
if (NS_FAILED( rv))
return( PR_FALSE);
m_encodeScanState = kScanningDataFork;
return( PR_TRUE);
}
break;
case kScanningDataFork: {
PRBool result = FillBufferFromFile();
if (!result)
return( PR_FALSE);
if (m_eof) {
m_eof = PR_FALSE;
result = ScanBuffer( pDone);
if (!result)
return( PR_FALSE);
m_pInputFile->CloseStream();
m_encodeScanState = kDoneWithFile;
return( PR_TRUE);
}
else
return( ScanBuffer( pDone));
}
break;
case kScanningRsrcFork: {
PRBool result = FillBufferFromFile();
if (!result)
return( PR_FALSE);
if (m_eof) {
m_eof = PR_FALSE;
result = ScanBuffer( pDone);
if (!result)
return( PR_FALSE);
m_pInputFile->CloseStream();
m_encodeScanState = kBeginDataFork;
return( PR_TRUE);
}
else
return( ScanBuffer( pDone));
}
break;
case kBeginResourceFork: {
if (!m_resourceForkSize) {
m_encodeScanState = kBeginDataFork;
return( PR_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( PR_TRUE);
}
break;
case kAddEntries: {
ShiftBuffer();
if (!AddEntries())
return( PR_FALSE);
m_encodeScanState = kBeginResourceFork;
return( ScanBuffer( pDone));
}
break;
case kDoneWithFile: {
ShiftBuffer();
m_eof = PR_TRUE;
if (!ScanBuffer( pDone))
return( PR_FALSE);
*pDone = PR_TRUE;
return( PR_TRUE);
}
break;
}
}
else
return( nsImportScanFile::Scan( pDone));
return( PR_FALSE);
}

View File

@ -0,0 +1,50 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsImportEncodeScan_h___
#define nsImportEncodeScan_h___
#include "nsIFileSpec.h"
#include "nsImportScanFile.h"
#include "nsString.h"
class nsImportEncodeScan : public nsImportScanFile {
public:
nsImportEncodeScan();
~nsImportEncodeScan();
PRBool InitEncodeScan( PRBool appleSingleEncode, nsIFileSpec *pSpec, const char *pName, PRUint8 * pBuf, PRUint32 sz);
void CleanUpEncodeScan( void);
virtual PRBool Scan( PRBool *pDone);
protected:
void FillInEntries( int numEntries);
PRBool AddEntries( void);
protected:
PRBool m_isAppleSingle;
nsIFileSpec * m_pInputFile;
int m_encodeScanState;
long m_resourceForkSize;
long m_dataForkSize;
nsCString m_useFileName;
};
#endif /* nsImportEncodeScan_h__ */

View File

@ -19,13 +19,16 @@
#include "nsIModule.h"
#include "nsIGenericFactory.h"
#include "nsIImportService.h"
#include "nsImportMimeEncode.h"
#include "ImportDebug.h"
static NS_DEFINE_CID(kImportServiceCID, NS_IMPORTSERVICE_CID);
static NS_DEFINE_CID(kImportMimeEncodeCID, NS_IMPORTMIMEENCODE_CID);
extern nsresult NS_NewImportService(nsIImportService** aImportService);
extern nsresult NS_NewImportMimeEncode( nsIImportMimeEncode **aMimeEncode);
// Module implementation for the import service library
class nsImportServiceModule : public nsIModule
@ -78,6 +81,7 @@ CreateNew##_name(nsISupports* aOuter, REFNSIID aIID, void **aResult) \
}
MAKE_CTOR(ImportService)
MAKE_CTOR(ImportMimeEncode)
//----------------------------------------------------------------------
@ -181,7 +185,10 @@ struct Components {
static Components gComponents[] = {
{ "Import Service Component", &kImportServiceCID,
"component://mozilla/import/import-service", },
{ "Import Mime Encoder", &kImportMimeEncodeCID,
"component://mozilla/import/import-mimeencode"},
};
#define NUM_COMPONENTS (sizeof(gComponents) / sizeof(gComponents[0]))
NS_IMETHODIMP

View File

@ -0,0 +1,458 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsString.h"
#include "nsCRT.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 = nsnull;
m_state = kNoState;
m_bytesProcessed = 0;
m_pInputBuf = nsnull;
m_pMimeFile = nsnull;
}
nsImportMimeEncode::~nsImportMimeEncode()
{
NS_IF_RELEASE( m_pMimeFile);
if (m_pInputBuf)
delete [] m_pInputBuf;
}
void nsImportMimeEncode::EncodeFile( nsIFileSpec *pInFile, ImportOutFile *pOut, const char *pFileName, const char *pMimeType)
{
m_fileName = pFileName;
m_mimeType = pMimeType;
m_pMimeFile = pInFile;
NS_IF_ADDREF( m_pMimeFile);
m_pOut = pOut;
m_state = kStartState;
}
void nsImportMimeEncode::CleanUp( void)
{
CleanUpEncodeScan();
}
PRBool nsImportMimeEncode::SetUpEncode( void)
{
nsCString errStr;
if (!m_pInputBuf) {
m_pInputBuf = new PRUint8[kEncodeBufferSz];
}
m_appleSingle = PR_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, m_pInputBuf, kEncodeBufferSz)) {
return( PR_FALSE);
}
m_state = kEncodeState;
m_lineLen = 0;
// Write out the boundary header
PRBool bResult = PR_TRUE;
bResult = m_pOut->WriteStr( "Content-type: ");
if (bResult)
bResult = m_pOut->WriteStr( m_mimeType);
#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;
PRBool 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);
}
PRBool nsImportMimeEncode::DoWork( PRBool *pDone)
{
*pDone = PR_FALSE;
switch( m_state) {
case kNoState:
return( PR_FALSE);
break;
case kStartState:
return( SetUpEncode());
break;
case kEncodeState:
if (!Scan( pDone)) {
CleanUp();
return( PR_FALSE);
}
if (*pDone) {
*pDone = PR_FALSE;
m_state = kDoneState;
}
break;
case kDoneState:
CleanUp();
m_state = kNoState;
*pDone = PR_TRUE;
break;
}
return( PR_TRUE);
}
static PRUint8 gBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
PRBool nsImportMimeEncode::ScanBuffer( PRBool *pDone)
{
PRUint32 pos = m_pos;
PRUint32 start = pos;
PRUint8 * pChar = m_pBuf + pos;
PRUint32 max = m_bytesInBuf;
PRUint8 byte[4];
PRUint32 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( PR_FALSE);
pos += 3;
pChar++;
lineLen += 4;
if (lineLen > 71) {
if (!m_pOut->WriteEol())
return( PR_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( PR_FALSE);
if (!m_pOut->WriteEol())
return( PR_FALSE);
}
else if (m_eof) {
/*
byte[0] = '=';
if (!m_pOut->WriteData( byte, 1))
return( FALSE);
*/
if (!m_pOut->WriteEol())
return( PR_FALSE);
}
m_lineLen = (int) lineLen;
m_pos = pos;
m_bytesProcessed += (pos - start);
return( PR_TRUE);
}
PRBool nsImportMimeEncode::TranslateFileName( nsCString& inFile, nsCString& outFile)
{
const PRUint8 * pIn = (const PRUint8 *) (const char *)inFile;
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, PR_TRUE)) {
outFile = inFile;
return( PR_FALSE);
}
else {
return( PR_TRUE);
}
}
else {
outFile = inFile;
return( PR_FALSE);
}
}
PRBool nsImportMimeEncode::WriteFileName( nsCString& fName, PRBool wasTrans, const char *pTag)
{
int tagNum = 0;
int idx = 0;
PRBool result = PR_TRUE;
int len;
nsCString numStr;
while ((((fName.Length() - idx) + nsCRT::strlen( pTag)) > 70) && result) {
len = 68 - nsCRT::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.Append( tagNum);
if (result)
result = m_pOut->WriteStr( (const char *)numStr);
if (wasTrans && result)
result = m_pOut->WriteStr( "*=");
else if (result)
result = m_pOut->WriteStr( "=\"");
if (result)
result = m_pOut->WriteData( ((const PRUint8 *)(const char *)fName) + 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.Append( tagNum);
if (result)
result = m_pOut->WriteStr( (const char *)numStr);
if (wasTrans && result)
result = m_pOut->WriteStr( "*=");
else if (result)
result = m_pOut->WriteStr( "=\"");
if (result)
result = m_pOut->WriteData( ((const PRUint8 *)(const char *)fName) + 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( (const char *)fName);
if (wasTrans && result)
result = m_pOut->WriteStr( "\x0D\x0A");
else if (result)
result = m_pOut->WriteStr( "\"\x0D\x0A");
}
return( result);
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
nsIImportMimeEncodeImpl::nsIImportMimeEncodeImpl()
{
m_pOut = nsnull;
m_pEncode = nsnull;
NS_INIT_ISUPPORTS();
}
nsIImportMimeEncodeImpl::~nsIImportMimeEncodeImpl()
{
if (m_pOut)
delete m_pOut;
if (m_pEncode)
delete m_pEncode;
}
NS_METHOD nsIImportMimeEncodeImpl::Create( nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
if (aOuter)
return NS_ERROR_NO_AGGREGATION;
nsIImportMimeEncodeImpl *it = new nsIImportMimeEncodeImpl();
if (it == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF( it);
nsresult rv = it->QueryInterface( aIID, aResult);
NS_RELEASE( it);
return rv;
}
NS_IMPL_ISUPPORTS(nsIImportMimeEncodeImpl, nsIImportMimeEncode::GetIID());
NS_METHOD nsIImportMimeEncodeImpl::EncodeFile(nsIFileSpec *inFile, nsIFileSpec *outFile, const char *fileName, const char *mimeType)
{
return( Initialize( inFile, outFile, fileName, mimeType));
}
NS_METHOD nsIImportMimeEncodeImpl::DoWork(PRBool *done, PRBool *_retval)
{
if (done && _retval && m_pEncode) {
*_retval = m_pEncode->DoWork( done);
return( NS_OK);
}
else
return( NS_ERROR_FAILURE);
}
NS_METHOD nsIImportMimeEncodeImpl::NumBytesProcessed(PRInt32 *_retval)
{
if (m_pEncode && _retval)
*_retval = m_pEncode->NumBytesProcessed();
return( NS_OK);
}
NS_METHOD nsIImportMimeEncodeImpl::DoEncoding(PRBool *_retval)
{
if (_retval && m_pEncode) {
PRBool done = PR_FALSE;
while (m_pEncode->DoWork( &done) && !done);
*_retval = done;
return( NS_OK);
}
else
return( NS_ERROR_FAILURE);
}
NS_METHOD nsIImportMimeEncodeImpl::Initialize(nsIFileSpec *inFile, nsIFileSpec *outFile, const char *fileName, const char *mimeType)
{
if (m_pEncode)
delete m_pEncode;
if (m_pOut)
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);
}
nsresult NS_NewImportMimeEncode( nsIImportMimeEncode **aEncoder)
{
return( nsIImportMimeEncodeImpl::Create( nsnull, nsIImportMimeEncode::GetIID(), (void **)aEncoder));
}

View File

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsImportMimeEncode_h__
#define nsImportMimeEncode_h__
#include "nsImportScanFile.h"
#include "ImportOutFile.h"
#include "nsImportEncodeScan.h"
#include "nsString.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( nsIFileSpec *pInFile, ImportOutFile *pOut, const char *pFileName, const char *pMimeType);
PRBool DoWork( PRBool *pDone);
long NumBytesProcessed( void) { long val = m_bytesProcessed; m_bytesProcessed = 0; return( val);}
protected:
void CleanUp( void);
PRBool SetUpEncode( void);
PRBool WriteFileName( nsCString& fName, PRBool wasTrans, const char *pTag);
PRBool TranslateFileName( nsCString& inFile, nsCString& outFile);
virtual PRBool ScanBuffer( PRBool *pDone);
protected:
nsCString m_fileName;
nsIFileSpec * m_pMimeFile;
ImportOutFile * m_pOut;
nsCString m_mimeType;
int m_state;
long m_bytesProcessed;
PRUint8 * m_pInputBuf;
PRBool m_appleSingle;
// Actual encoding variables
int m_lineLen;
};
class nsIImportMimeEncodeImpl : public nsIImportMimeEncode {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIIMPORTMIMEENCODE
nsIImportMimeEncodeImpl();
virtual ~nsIImportMimeEncodeImpl();
static NS_METHOD Create( nsISupports *aOuter, REFNSIID aIID, void **aResult);
private:
ImportOutFile * m_pOut;
nsImportMimeEncode * m_pEncode;
};
#endif /* nsImportMimeEncode_h__ */

View File

@ -0,0 +1,231 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsIFileSpec.h"
#include "nsCRT.h"
#include "nsImportScanFile.h"
#include "ImportCharSet.h"
nsImportScanFile::nsImportScanFile()
{
m_allocated = PR_FALSE;
m_eof = PR_FALSE;
m_pFile = nsnull;
m_pBuf = nsnull;
}
nsImportScanFile::nsImportScanFile( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz)
{
m_allocated = PR_FALSE;
m_eof = PR_FALSE;
InitScan( pSpec, pBuf, sz);
}
nsImportScanFile::~nsImportScanFile()
{
if (m_allocated) {
CleanUpScan();
}
NS_IF_RELEASE( m_pFile);
}
PRBool nsImportScanFile::OpenScan( nsIFileSpec *pSpec, PRUint32 bufSz)
{
if (!bufSz)
bufSz = 32 * 1024;
if (!m_pBuf) {
m_pBuf = new PRUint8[bufSz];
}
PRBool open = PR_FALSE;
nsresult rv = pSpec->IsStreamOpen( &open);
if (NS_FAILED( rv) || !open) {
rv = pSpec->OpenStreamForReading();
if (NS_FAILED( rv)) {
delete [] m_pBuf;
m_pBuf = nsnull;
return( PR_FALSE);
}
}
m_pFile = pSpec;
NS_IF_ADDREF( m_pFile);
m_allocated = PR_TRUE;
m_bytesInBuf = 0;
m_pos = 0;
m_bufSz = bufSz;
return( PR_TRUE);
}
void nsImportScanFile::InitScan( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz)
{
m_pFile = pSpec;
NS_IF_ADDREF( pSpec);
m_pBuf = pBuf;
m_bufSz = sz;
m_bytesInBuf = 0;
m_pos = 0;
}
void nsImportScanFile::CleanUpScan( void)
{
NS_IF_RELEASE( m_pFile);
m_pFile = nsnull;
if (m_allocated) {
if (m_pBuf)
delete [] m_pBuf;
m_pBuf = NULL;
}
}
void nsImportScanFile::ShiftBuffer( void)
{
PRUint8 * pTop;
PRUint8 * pCurrent;
if (m_pos < m_bytesInBuf) {
pTop = m_pBuf;
pCurrent = pTop + m_pos;
PRUint32 cnt = m_bytesInBuf - m_pos;
while (cnt) {
*pTop = *pCurrent;
pTop++; pCurrent++;
cnt--;
}
}
m_bytesInBuf -= m_pos;
m_pos = 0;
}
PRBool nsImportScanFile::FillBufferFromFile( void)
{
PRBool eof = PR_FALSE;
nsresult rv = m_pFile->Eof( &eof);
if (eof) {
return( PR_FALSE);
}
// Fill up a buffer and scan it
ShiftBuffer();
// Read in some more bytes
PRUint32 cnt = m_bufSz - m_bytesInBuf;
// To distinguish from disk errors
// Check first for end of file?
// Set a done flag if true...
PRInt32 read;
char *pBuf = (char *)m_pBuf;
pBuf += m_bytesInBuf;
rv = m_pFile->Read( &pBuf, (PRInt32) cnt, &read);
if (NS_FAILED( rv))
return( PR_FALSE);
eof = PR_FALSE;
rv = m_pFile->Eof( &eof);
if (eof)
m_eof = PR_TRUE;
m_bytesInBuf += cnt;
return( PR_TRUE);
}
PRBool nsImportScanFile::Scan( PRBool *pDone)
{
PRBool eof = PR_FALSE;
nsresult rv = m_pFile->Eof( &eof);
if (eof) {
if (m_pos < m_bytesInBuf) {
ScanBuffer( pDone);
}
*pDone = PR_TRUE;
return( PR_TRUE);
}
// Fill up a buffer and scan it
if (!FillBufferFromFile())
return( PR_FALSE);
return( ScanBuffer( pDone));
}
PRBool nsImportScanFile::ScanBuffer( PRBool *)
{
return( PR_TRUE);
}
PRBool nsImportScanFileLines::ScanBuffer( PRBool *pDone)
{
// m_pos, m_bytesInBuf, m_eof, m_pBuf are relevant
PRUint32 pos = m_pos;
PRUint32 max = m_bytesInBuf;
PRUint8 * pChar = m_pBuf + pos;
PRUint32 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 = PR_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 = PR_TRUE;
}
break;
}
if (!ProcessLine( m_pBuf + startPos, pos - startPos, pDone)) {
return( PR_FALSE);
}
m_pos = pos;
}
return( PR_TRUE);
}

View File

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsImportScanFile_h__
#define nsImportScanFile_h__
#include "nsIFileSpec.h"
class nsImportScanFile {
public:
nsImportScanFile();
nsImportScanFile( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz);
virtual ~nsImportScanFile();
void InitScan( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz);
PRBool OpenScan( nsIFileSpec *pSpec, PRUint32 bufSz = 4096);
void CleanUpScan( void);
virtual PRBool Scan( PRBool *pDone);
protected:
void ShiftBuffer( void);
PRBool FillBufferFromFile( void);
virtual PRBool ScanBuffer( PRBool *pDone);
protected:
nsIFileSpec * m_pFile;
PRUint8 * m_pBuf;
PRUint32 m_bufSz;
PRUint32 m_bytesInBuf;
PRUint32 m_pos;
PRBool m_eof;
PRBool m_allocated;
};
class nsImportScanFileLines : public nsImportScanFile {
public:
nsImportScanFileLines() {m_needEol = PR_FALSE;}
void ResetLineScan( void) { m_needEol = PR_FALSE;}
virtual PRBool ProcessLine( PRUint8 * /* pLine */, PRUint32 /* len */, PRBool * /* pDone */ ) {return( PR_TRUE);}
protected:
virtual PRBool ScanBuffer( PRBool *pDone);
PRBool m_needEol;
};
#endif /* nsImportScanFile_h__ */

View File

@ -0,0 +1,309 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "ImportOutFile.h"
#include "nsImportTranslator.h"
#include "ImportCharSet.h"
PRBool nsImportTranslator::ConvertToFile( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed)
{
if (pProcessed)
*pProcessed = inLen;
return( pOutFile->WriteData( pIn, inLen));
}
void CMHTranslator::ConvertBuffer( const PRUint8 * pIn, PRUint32 inLen, PRUint8 * 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;
}
PRBool CMHTranslator::ConvertToFile( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed)
{
PRUint8 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( PR_FALSE);
ImportCharSet::ByteToHex( *pIn, hex);
if (!pOutFile->WriteData( hex, 2))
return( PR_FALSE);
}
else {
if (!pOutFile->WriteByte( *pIn))
return( PR_FALSE);
}
pIn++; inLen--;
}
if (pProcessed)
*pProcessed = inLen;
return( PR_TRUE);
}
PRBool C2047Translator::ConvertToFileQ( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed)
{
if (!inLen)
return( PR_TRUE);
int maxLineLen = 64;
int curLineLen = m_startLen;
PRBool startLine = PR_TRUE;
PRUint8 hex[2];
while (inLen) {
if (startLine) {
if (!pOutFile->WriteStr( " =?"))
return( PR_FALSE);
if (!pOutFile->WriteStr( m_charset))
return( PR_FALSE);
if (!pOutFile->WriteStr( "?q?"))
return( PR_FALSE);
curLineLen += (6 + m_charset.Length());
startLine = PR_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( PR_FALSE);
ImportCharSet::ByteToHex( *pIn, hex);
if (!pOutFile->WriteData( hex, 2))
return( PR_FALSE);
curLineLen += 3;
}
else {
if (!pOutFile->WriteByte( *pIn))
return( PR_FALSE);
curLineLen++;
}
pIn++; inLen--;
if (curLineLen > maxLineLen) {
if (!pOutFile->WriteStr( "?="))
return( PR_FALSE);
if (inLen) {
if (!pOutFile->WriteStr( "\x0D\x0A "))
return( PR_FALSE);
}
startLine = PR_TRUE;
curLineLen = 0;
}
}
if (!startLine) {
// end the encoding!
if (!pOutFile->WriteStr( "?="))
return( PR_FALSE);
}
if (pProcessed)
*pProcessed = inLen;
return( PR_TRUE);
}
PRBool C2047Translator::ConvertToFile( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed)
{
if (m_useQuotedPrintable)
return( ConvertToFileQ( pIn, inLen, pOutFile, pProcessed));
if (!inLen)
return( PR_TRUE);
int maxLineLen = 64;
int curLineLen = m_startLen;
PRBool startLine = PR_TRUE;
int encodeMax;
PRUint8 * pEncoded = new PRUint8[maxLineLen * 2];
while (inLen) {
if (startLine) {
if (!pOutFile->WriteStr( " =?")) {
delete [] pEncoded;
return( PR_FALSE);
}
if (!pOutFile->WriteStr( m_charset)) {
delete [] pEncoded;
return( PR_FALSE);
}
if (!pOutFile->WriteStr( "?b?")) {
delete [] pEncoded;
return( PR_FALSE);
}
curLineLen += (6 + m_charset.Length());
startLine = PR_FALSE;
}
encodeMax = maxLineLen - curLineLen;
encodeMax *= 3;
encodeMax /= 4;
if ((PRUint32)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( PR_FALSE);
}
pIn += encodeMax;
inLen -= encodeMax;
startLine = PR_TRUE;
curLineLen = 0;
if (!pOutFile->WriteStr( "?=")) {
delete [] pEncoded;
return( PR_FALSE);
}
if (inLen) {
if (!pOutFile->WriteStr( "\x0D\x0A ")) {
delete [] pEncoded;
return( PR_FALSE);
}
}
}
delete [] pEncoded;
if (pProcessed)
*pProcessed = inLen;
return( PR_TRUE);
}
PRUint32 UMimeEncode::GetBufferSize( PRUint32 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 PRUint8 gBase64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
PRUint32 UMimeEncode::ConvertBuffer( const PRUint8 * pIn, PRUint32 inLen, PRUint8 * pOut, PRUint32 maxLen, PRUint32 firstLineLen, const char * pEolStr)
{
PRUint32 pos = 0;
PRUint32 len = 0;
PRUint32 lineLen = 0;
PRUint32 maxLine = firstLineLen;
int eolLen = 0;
if (pEolStr)
eolLen = nsCRT::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) {
nsCRT::memcpy( pOut, pEolStr, eolLen);
pOut += eolLen;
len += eolLen;
}
}
}
if ((pos < inLen) && ((lineLen + 3) > maxLine)) {
lineLen = 0;
maxLine = maxLen;
if (pEolStr) {
nsCRT::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,78 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsImportTranslator_h___
#define nsImportTranslator_h___
#include "nscore.h"
#include "nsString.h"
#include "nsCRT.h"
class ImportOutFile;
class UMimeEncode {
public:
static PRUint32 GetBufferSize( PRUint32 inByes);
static PRUint32 ConvertBuffer( const PRUint8 * pIn, PRUint32 inLen, PRUint8 *pOut, PRUint32 maxLen = 72, PRUint32 firstLineLen = 72, const char * pEolStr = nsnull);
};
class nsImportTranslator {
public:
virtual ~nsImportTranslator() {}
virtual PRBool Supports8bitEncoding( void) { return( PR_FALSE);}
virtual PRUint32 GetMaxBufferSize( PRUint32 inLen) { return( inLen + 1);}
virtual void ConvertBuffer( const PRUint8 * pIn, PRUint32 inLen, PRUint8 * pOut) { nsCRT::memcpy( pOut, pIn, inLen); pOut[inLen] = 0;}
virtual PRBool ConvertToFile( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed = nsnull);
virtual PRBool FinishConvertToFile( ImportOutFile * /* pOutFile */) { return( PR_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 PRUint32 GetMaxBufferSize( PRUint32 inLen) { return( (inLen * 3) + 1);}
virtual void ConvertBuffer( const PRUint8 * pIn, PRUint32 inLen, PRUint8 * pOut);
virtual PRBool ConvertToFile( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed = nsnull);
};
// Specialized encoder, not a vaild language translator, used for mail headers
// rfc2047
class C2047Translator : public nsImportTranslator {
public:
virtual ~C2047Translator() {}
C2047Translator( const char *pCharset, PRUint32 headerLen) { m_charset = pCharset; m_startLen = headerLen; m_useQuotedPrintable = PR_FALSE;}
void SetUseQuotedPrintable( void) { m_useQuotedPrintable = PR_TRUE;}
virtual PRBool ConvertToFile( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed = nsnull);
PRBool ConvertToFileQ( const PRUint8 * pIn, PRUint32 inLen, ImportOutFile *pOutFile, PRUint32 *pProcessed);
protected:
PRBool m_useQuotedPrintable;
nsCString m_charset;
PRUint32 m_startLen;
};
#endif /* nsImportTranslator_h__ */

View File

@ -0,0 +1,51 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
#
# The following are used by the outlook express import code to display status/error
# and informational messages
#
# Short name of import module
## @name OUTLOOKIMPORT_NAME
## @loc None
2000=Outlook
# Description of import module
## @name OUTLOOKIMPORT_DESCRIPTION
## @loc None
2001=Outlook mail and address books
# Success message
## @name OUTLOOKIMPORT_MAILBOX_SUCCESS
## @loc None
2002=Mailbox %S, imported %d messages
# Error message
## @name OUTLOOKIMPORT_MAILBOX_BADPARAM
## @loc None
2003=Bad parameter passed to import mailbox.
# Error message
## @name OUTLOOKIMPORT_MAILBOX_CONVERTERROR
## @loc None
2004=Error importing mailbox %S, all messages may not be imported from this mailbox.