Just adding files to the tree - NOT PART OF THE BUILD!!!

This commit is contained in:
rhp%netscape.com 2000-04-18 23:59:32 +00:00
parent 7d99e7f231
commit 3e9f0c30bb
21 changed files with 2773 additions and 0 deletions

View File

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

View File

@ -0,0 +1,21 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
nsAbSyncCID.h

View File

@ -0,0 +1,54 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = absyncsvc
LIBRARY_NAME = absyncsvc
IS_COMPONENT = 1
CPPSRCS = nsAbSyncFactory.cpp
EXPORTS = nsAbSyncCID.h
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/libabsync_s.a \
$(NULL)
EXTRA_DSO_LDOPTS = \
$(MKSHLIB_FORCE_ALL) \
$(SHARED_LIBRARY_LIBS) \
$(MKSHLIB_UNFORCE_ALL) \
-L$(DIST)/bin \
-L$(DIST)/lib \
$(XPCOM_LIBS) \
-lmozjs \
-lmsgbaseutil \
$(NSPR_LIBS) \
$(NULL)
include $(topsrcdir)/config/rules.mk
$(LIBRARY) $(SHARED_LIBRARY): $(SHARED_LIBRARY_LIBS) Makefile

View File

@ -0,0 +1,54 @@
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
MODULE=absyncsvc
################################################################################
## exports
EXPORTS = \
nsAbSyncCID.h \
$(NULL)
################################################################################
## library
LIBNAME = .\$(OBJDIR)\absyncsvc
DLL = $(LIBNAME).dll
OBJS=\
.\$(OBJDIR)\nsAbSyncFactory.obj \
$(NULL)
LLIBS= \
$(LLIBS) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\js32$(VERSION_NUMBER).lib \
$(DIST)\lib\absync_s.lib \
$(DIST)\lib\msgbsutl.lib \
$(LIBNSPR) \
$(NULL)
include <$(DEPTH)/config/rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) $(LIBNAME).$(DLL_SUFFIX) $(DIST)\bin\components
$(MAKE_INSTALL) $(LIBNAME).$(LIB_SUFFIX) $(DIST)\lib

View File

@ -0,0 +1,76 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsAbSyncCID_h__
#define nsAbSyncCID_h__
#include "nsISupports.h"
#include "nsIFactory.h"
#include "nsIComponentManager.h"
//
// Ab Sync Service
//
#define NS_ABSYNC_SERVICE_CID \
{ /* {3C21BB39-0A87-11d4-8FD6-00A024A7D144} */ \
0x3c21bb39, 0xa87, 0x11d4, \
{ 0x8f, 0xd6, 0x0, 0xa0, 0x24, 0xa7, 0xd1, 0x44 } }
#define NS_ABSYNC_SERVICE_PROGID \
"component://netscape/absync"
//
// Ab Sync Listener
//
#define NS_ABSYNC_LISTENER_CID \
{ /* {3C21BB44-0A87-11d4-8FD6-00A024A7D144} */ \
0x3c21bb44, 0xa87, 0x11d4, \
{ 0x8f, 0xd6, 0x0, 0xa0, 0x24, 0xa7, 0xd1, 0x44 } }
#define NS_ABSYNC_LISTENER_PROGID \
"component://netscape/absync/listener"
//
// Ab Sync Post Engine
//
#define NS_ABSYNC_POST_ENGINE_CID \
{ /* {3C21BB9f-0A87-11d4-8FD6-00A024A7D144} */ \
0x3c21bb9f, 0xa87, 0x11d4, \
{ 0x8f, 0xd6, 0x0, 0xa0, 0x24, 0xa7, 0xd1, 0x44 } }
#define NS_ABSYNC_POST_ENGINE_PROGID \
"component://netscape/absync/postengine"
//
// Ab Sync Post Listener
//
#define NS_ABSYNC_POST_LISTENER_CID \
{ /* {3C21BBcc-0A87-11d4-8FD6-00A024A7D144} */ \
0x3c21bbcc, 0xa87, 0x11d4, \
{ 0x8f, 0xd6, 0x0, 0xa0, 0x24, 0xa7, 0xd1, 0x44 } }
#define NS_ABSYNC_POST_LISTENER_PROGID \
"component://netscape/absync/postlistener"
#endif // nsAbSyncCID_h__

View File

@ -0,0 +1,59 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "msgCore.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsIFactory.h"
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsIModule.h"
#include "pratom.h"
#include "nsAbSyncCID.h"
/* Include all of the interfaces our factory can generate components for */
#include "nsAbSync.h"
#include "nsAbSyncPostEngine.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbSync);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbSyncPostEngine);
////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////
static nsModuleComponentInfo components[] =
{
{ "Addressbook Sync",
NS_ABSYNC_SERVICE_CID,
NS_ABSYNC_SERVICE_PROGID,
nsAbSyncConstructor },
{ "Addressbook Sync Post Engine",
NS_ABSYNC_POST_ENGINE_CID,
NS_ABSYNC_POST_ENGINE_PROGID,
nsAbSyncPostEngineConstructor }
};
NS_IMPL_NSGETMODULE("nsAbSyncModule", components)

View File

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

View File

@ -0,0 +1,42 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = absync
EXPORTS = \
$(NULL)
XPIDLSRCS = \
nsIAbSync.idl \
nsIAbSyncListener.idl \
nsIAbSyncPostEngine.idl \
nsIAbSyncPostListener.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

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

View File

@ -0,0 +1,50 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIAbSyncListener.idl"
interface nsIAbSyncState
{
const long nsIAbSyncIdle = 0;
const long nsIAbSyncRunning = 1;
};
[scriptable, uuid(74872D27-0A4E-11d4-8FD6-00A024A7D144)]
interface nsIAbSync : nsISupports {
/*
* This is the primary interface for performing AB Sync operations
*/
/* Add or remove a listener for this particular sync operation */
void AddSyncListener(in nsIAbSyncListener aListener);
void RemoveSyncListener(in nsIAbSyncListener aListener);
/* Get the nsIAbSyncPostEngineState of the sync operation */
PRInt32 GetCurrentState();
/*
* Send the protocol request and get a transaction ID in return that
* will be sent along with all sync listener operations
*/
void PerformAbSync(out PRInt32 aTransactionID);
};

View File

@ -0,0 +1,63 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsrootidl.idl"
#include "nsIFileSpec.idl"
%{C++
%}
[scriptable, uuid(E0ED29E0-098A-11d4-8FD6-00A024A7D144)]
interface nsIAbSyncListener : nsISupports {
/**
* Notify the observer that the AB Sync operation has begun. This method is
* called only once, at the beginning of a sync transaction
*
*/
void OnStartOperation(in PRInt32 aTransactionID, in PRUint32 aMsgSize);
/**
* Notify the observer that progress as occurred for the AB Sync operation
*/
void OnProgress(in PRInt32 aTransactionID, in PRUint32 aProgress, in PRUint32 aProgressMax);
/**
* Notify the observer with a status message for sync operation
*/
void OnStatus(in PRInt32 aTransactionID, in wstring aMsg);
/**
* Notify the observer that the AB Sync operation has been completed.
*
* This method is called regardless of whether the the operation was
* successful.
*
* aTransactionID - the ID for this particular request
* aStatus - Status code for the sync request
* aMsg - A text string describing the error (if any).
*/
void OnStopOperation(in PRInt32 aTransactionID, in nsresult aStatus,
in wstring aMsg);
};

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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsIAbSyncPostListener.idl"
[scriptable, uuid(E0ED29D3-BEEF-11d4-8FD6-00A024A7D144)]
interface nsIAbSyncPostEngineState
{
const long nsIAbSyncPostIdle = 0;
const long nsIAbSyncPostRunning = 1;
};
[scriptable, uuid(E0ED29D3-098A-11d4-8FD6-00A024A7D144)]
interface nsIAbSyncPostEngine : nsISupports {
/*
* This is the primary interface for posting operations to the
* Address Book server in the sky
*/
/* Add or remove a listener for this particular sync operation */
void AddPostListener(in nsIAbSyncPostListener aListener);
void RemovePostListener(in nsIAbSyncPostListener aListener);
/* Get the nsIAbSyncPostEngineState of the sync operation */
PRInt32 GetCurrentState();
/*
* Send the protocol request and get a transaction ID in return that
* will be sent along with all sync listener operations
*/
void SendAbRequest(in string aSpec, in string aProtocolRequest, in PRInt32 aTransactionID);
};

View File

@ -0,0 +1,66 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
#include "nsrootidl.idl"
#include "nsIFileSpec.idl"
%{C++
%}
[scriptable, uuid(E0ED29E0-098A-11d4-8FD6-00A024A7BEEF)]
interface nsIAbSyncPostListener : nsISupports {
/**
* Notify the observer that the AB Sync operation has begun. This method is
* called only once, at the beginning of a sync transaction
*
*/
void OnStartOperation(in PRInt32 aTransactionID, in PRUint32 aMsgSize);
/**
* Notify the observer that progress as occurred for the AB Sync operation
*/
void OnProgress(in PRInt32 aTransactionID, in PRUint32 aProgress, in PRUint32 aProgressMax);
/**
* Notify the observer with a status message for sync operation
*/
void OnStatus(in PRInt32 aTransactionID, in wstring aMsg);
/**
* Notify the observer that the AB Sync operation has been sent. This
* method is called once when the networking library has finished processing
* the sync operation.
*
* This method is called regardless of whether the the operation was
* successful.
*
* aTransactionID - the ID for this particular request
* aStatus - Status code for the sync request
* aMsg - A text string describing the error (if any).
* aProtocolResponse - The protocol response sent by the AB server
*/
void OnStopOperation(in PRInt32 aTransactionID, in nsresult aStatus,
in wstring aMsg, in string aProtocolResponse);
};

View File

@ -0,0 +1,53 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = absync
LIBRARY_NAME = absync_s
CPPSRCS = \
nsAbSyncPostEngine.cpp \
nsAbSync.cpp \
nsAbSyncCRCModel.cpp \
$(NULL)
EXPORTS = \
nsAbSyncPostEngine.h \
nsAbSync.h \
nsAbSyncCRCModel.h \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk
ifeq ($(OS_ARCH), Linux)
DEFINES += -D_BSD_SOURCE
endif

View File

@ -0,0 +1,52 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
MODULE= absync
include <$(DEPTH)\config\config.mak>
################################################################################
## exports
EXPORTS= nsAbSyncPostEngine.h \
nsAbSync.h \
nsAbSyncCRCModel.h \
$(NULL)
################################################################################
## library
LIBRARY_NAME=absync_s
CPP_OBJS= .\$(OBJDIR)\nsAbSyncPostEngine.obj \
.\$(OBJDIR)\nsAbSync.obj \
.\$(OBJDIR)\nsAbSyncCRCModel.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@ -0,0 +1,968 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsAbSync.h"
#include "prmem.h"
#include "nsAbSyncCID.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
#include "prprf.h"
#include "nsIAddrBookSession.h"
#include "nsAbBaseCID.h"
#include "nsIRDFResource.h"
#include "nsIRDFService.h"
#include "nsRDFCID.h"
#include "nsIFileLocator.h"
#include "nsFileLocations.h"
static NS_DEFINE_CID(kCAbSyncPostEngineCID, NS_ABSYNC_POST_ENGINE_CID);
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kAddrBookSessionCID, NS_ADDRBOOKSESSION_CID);
static NS_DEFINE_CID(kAddressBookDBCID, NS_ADDRDATABASE_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kFileLocatorCID, NS_FILELOCATOR_CID);
// Address book fields!
const char *kFirstNameColumn = "FirstName";
const char *kLastNameColumn = "LastName";
const char *kDisplayNameColumn = "DisplayName";
const char *kNicknameColumn = "NickName";
const char *kPriEmailColumn = "PrimaryEmail";
const char *k2ndEmailColumn = "SecondEmail";
const char *kPlainTextColumn = "SendPlainText";
const char *kWorkPhoneColumn = "WorkPhone";
const char *kHomePhoneColumn = "HomePhone";
const char *kFaxColumn = "FaxNumber";
const char *kPagerColumn = "PagerNumber";
const char *kCellularColumn = "CellularNumber";
const char *kHomeAddressColumn = "HomeAddress";
const char *kHomeAddress2Column = "HomeAddress2";
const char *kHomeCityColumn = "HomeCity";
const char *kHomeStateColumn = "HomeState";
const char *kHomeZipCodeColumn = "HomeZipCode";
const char *kHomeCountryColumn = "HomeCountry";
const char *kWorkAddressColumn = "WorkAddress";
const char *kWorkAddress2Column = "WorkAddress2";
const char *kWorkCityColumn = "WorkCity";
const char *kWorkStateColumn = "WorkState";
const char *kWorkZipCodeColumn = "WorkZipCode";
const char *kWorkCountryColumn = "WorkCountry";
const char *kJobTitleColumn = "JobTitle";
const char *kDepartmentColumn = "Department";
const char *kCompanyColumn = "Company";
const char *kWebPage1Column = "WebPage1";
const char *kWebPage2Column = "WebPage2";
const char *kBirthYearColumn = "BirthYear";
const char *kBirthMonthColumn = "BirthMonth";
const char *kBirthDayColumn = "BirthDay";
const char *kCustom1Column = "Custom1";
const char *kCustom2Column = "Custom2";
const char *kCustom3Column = "Custom3";
const char *kCustom4Column = "Custom4";
const char *kNotesColumn = "Notes";
const char *kLastModifiedDateColumn = "LastModifiedDate";
// Server record fields!
const char *kServerFirstNameColumn = "fname";
const char *kServerLastNameColumn = "lname";
const char *kServerDisplayNameColumn = "screen_name";
const char *kServerNicknameColumn = "NickName";
const char *kServerPriEmailColumn = "email1";
const char *kServer2ndEmailColumn = "email2";
const char *kServerPlainTextColumn = "SendPlainText";
const char *kServerWorkPhoneColumn = "work_phone";
const char *kServerHomePhoneColumn = "home_phone";
const char *kServerFaxColumn = "fax";
const char *kServerPagerColumn = "pager";
const char *kServerCellularColumn = "cell_phone";
const char *kServerHomeAddressColumn = "home_add1";
const char *kServerHomeAddress2Column = "home_add2";
const char *kServerHomeCityColumn = "home_city";
const char *kServerHomeStateColumn = "home_state";
const char *kServerHomeZipCodeColumn = "home_zip";
const char *kServerHomeCountryColumn = "home_country";
const char *kServerWorkAddressColumn = "work_add1";
const char *kServerWorkAddress2Column = "work_add2";
const char *kServerWorkCityColumn = "work_city";
const char *kServerWorkStateColumn = "work_state";
const char *kServerWorkZipCodeColumn = "work_zip";
const char *kServerWorkCountryColumn = "work_country";
const char *kServerJobTitleColumn = "JobTitle";
const char *kServerDepartmentColumn = "Department";
const char *kServerCompanyColumn = "Company";
const char *kServerWebPage1Column = "WebPage1";
const char *kServerWebPage2Column = "WebPage2";
const char *kServerBirthYearColumn = "BirthYear";
const char *kServerBirthMonthColumn = "BirthMonth";
const char *kServerBirthDayColumn = "BirthDay";
const char *kServerCustom1Column = "Custom1";
const char *kServerCustom2Column = "Custom2";
const char *kServerCustom3Column = "Custom3";
const char *kServerCustom4Column = "Custom4";
const char *kServerNotesColumn = "Notes";
const char *kServerLastModifiedDateColumn = "LastModifiedDate";
// So far, we aren't really doing anything with these!
const char *kAddressCharSetColumn = "AddrCharSet";
const char *kMailListName = "ListName";
const char *kMailListNickName = "ListNickName";
const char *kMailListDescription = "ListDescription";
const char *kMailListTotalAddresses = "ListTotalAddresses";
// So far, we aren't really doing anything with these!
/* Implementation file */
NS_IMPL_ISUPPORTS1(nsAbSync, nsIAbSync)
nsAbSync::nsAbSync()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
mListenerArray = nsnull;
mListenerArrayCount = 0;
mCurrentState = nsIAbSyncState::nsIAbSyncIdle;
mTransactionID = 100;
mPostEngine = nsnull;
mAbSyncServer = nsnull;
mAbSyncPort = 5000;
mAbSyncAddressBook = nsnull;
mAbSyncAddressBookFileName = nsnull;
mHistoryFile = nsnull;
mOldSyncMapingTable = nsnull;
mNewSyncMapingTable = nsnull;
InitSchemaColumns();
}
nsresult
nsAbSync::InternalCleanup()
{
/* cleanup code */
DeleteListeners();
PR_FREEIF(mAbSyncServer);
PR_FREEIF(mAbSyncAddressBook);
PR_FREEIF(mAbSyncAddressBookFileName);
if (mHistoryFile)
mHistoryFile->CloseStream();
return NS_OK;
}
nsAbSync::~nsAbSync()
{
if (mPostEngine)
mPostEngine->RemovePostListener((nsIAbSyncPostListener *)this);
InternalCleanup();
}
NS_IMETHODIMP
nsAbSync::InitSchemaColumns()
{
// First, setup the local address book fields...
mSchemaMappingList[0].abField = kFirstNameColumn;
mSchemaMappingList[1].abField = kLastNameColumn;
mSchemaMappingList[2].abField = kDisplayNameColumn;
mSchemaMappingList[3].abField = kNicknameColumn;
mSchemaMappingList[4].abField = kPriEmailColumn;
mSchemaMappingList[5].abField = k2ndEmailColumn;
mSchemaMappingList[6].abField = kPlainTextColumn;
mSchemaMappingList[7].abField = kWorkPhoneColumn;
mSchemaMappingList[8].abField = kHomePhoneColumn;
mSchemaMappingList[9].abField = kFaxColumn;
mSchemaMappingList[10].abField = kPagerColumn;
mSchemaMappingList[11].abField = kCellularColumn;
mSchemaMappingList[12].abField = kHomeAddressColumn;
mSchemaMappingList[13].abField = kHomeAddress2Column;
mSchemaMappingList[14].abField = kHomeCityColumn;
mSchemaMappingList[15].abField = kHomeStateColumn;
mSchemaMappingList[16].abField = kHomeZipCodeColumn;
mSchemaMappingList[17].abField = kHomeCountryColumn;
mSchemaMappingList[18].abField = kWorkAddressColumn;
mSchemaMappingList[19].abField = kWorkAddress2Column;
mSchemaMappingList[20].abField = kWorkCityColumn;
mSchemaMappingList[21].abField = kWorkStateColumn;
mSchemaMappingList[22].abField = kWorkZipCodeColumn;
mSchemaMappingList[23].abField = kWorkCountryColumn;
mSchemaMappingList[24].abField = kJobTitleColumn;
mSchemaMappingList[25].abField = kDepartmentColumn;
mSchemaMappingList[26].abField = kCompanyColumn;
mSchemaMappingList[27].abField = kWebPage1Column;
mSchemaMappingList[28].abField = kWebPage2Column;
mSchemaMappingList[29].abField = kBirthYearColumn;
mSchemaMappingList[30].abField = kBirthMonthColumn;
mSchemaMappingList[31].abField = kBirthDayColumn;
mSchemaMappingList[32].abField = kCustom1Column;
mSchemaMappingList[33].abField = kCustom2Column;
mSchemaMappingList[34].abField = kCustom3Column;
mSchemaMappingList[35].abField = kCustom4Column;
mSchemaMappingList[36].abField = kNotesColumn;
mSchemaMappingList[37].abField = kLastModifiedDateColumn;
// Now setup the server fields...
mSchemaMappingList[0].serverField = kServerFirstNameColumn;
mSchemaMappingList[1].serverField = kServerLastNameColumn;
mSchemaMappingList[2].serverField = kServerDisplayNameColumn;
mSchemaMappingList[3].serverField = kServerNicknameColumn;
mSchemaMappingList[4].serverField = kServerPriEmailColumn;
mSchemaMappingList[5].serverField = kServer2ndEmailColumn;
mSchemaMappingList[6].serverField = kServerPlainTextColumn;
mSchemaMappingList[7].serverField = kServerWorkPhoneColumn;
mSchemaMappingList[8].serverField = kServerHomePhoneColumn;
mSchemaMappingList[9].serverField = kServerFaxColumn;
mSchemaMappingList[10].serverField = kServerPagerColumn;
mSchemaMappingList[11].serverField = kServerCellularColumn;
mSchemaMappingList[12].serverField = kServerHomeAddressColumn;
mSchemaMappingList[13].serverField = kServerHomeAddress2Column;
mSchemaMappingList[14].serverField = kServerHomeCityColumn;
mSchemaMappingList[15].serverField = kServerHomeStateColumn;
mSchemaMappingList[16].serverField = kServerHomeZipCodeColumn;
mSchemaMappingList[17].serverField = kServerHomeCountryColumn;
mSchemaMappingList[18].serverField = kServerWorkAddressColumn;
mSchemaMappingList[19].serverField = kServerWorkAddress2Column;
mSchemaMappingList[20].serverField = kServerWorkCityColumn;
mSchemaMappingList[21].serverField = kServerWorkStateColumn;
mSchemaMappingList[22].serverField = kServerWorkZipCodeColumn;
mSchemaMappingList[23].serverField = kServerWorkCountryColumn;
mSchemaMappingList[24].serverField = kServerJobTitleColumn;
mSchemaMappingList[25].serverField = kServerDepartmentColumn;
mSchemaMappingList[26].serverField = kServerCompanyColumn;
mSchemaMappingList[27].serverField = kServerWebPage1Column;
mSchemaMappingList[28].serverField = kServerWebPage2Column;
mSchemaMappingList[29].serverField = kServerBirthYearColumn;
mSchemaMappingList[30].serverField = kServerBirthMonthColumn;
mSchemaMappingList[31].serverField = kServerBirthDayColumn;
mSchemaMappingList[32].serverField = kServerCustom1Column;
mSchemaMappingList[33].serverField = kServerCustom2Column;
mSchemaMappingList[34].serverField = kServerCustom3Column;
mSchemaMappingList[35].serverField = kServerCustom4Column;
mSchemaMappingList[36].serverField = kServerNotesColumn;
mSchemaMappingList[37].serverField = kServerLastModifiedDateColumn;
return NS_OK;
}
/* void AddSyncListener (in nsIAbSyncListener aListener); */
NS_IMETHODIMP nsAbSync::AddSyncListener(nsIAbSyncListener *aListener)
{
if ( (mListenerArrayCount > 0) || mListenerArray )
{
++mListenerArrayCount;
mListenerArray = (nsIAbSyncListener **)
PR_Realloc(*mListenerArray, sizeof(nsIAbSyncListener *) * mListenerArrayCount);
if (!mListenerArray)
return NS_ERROR_OUT_OF_MEMORY;
else
{
mListenerArray[mListenerArrayCount - 1] = aListener;
return NS_OK;
}
}
else
{
mListenerArrayCount = 1;
mListenerArray = (nsIAbSyncListener **) PR_Malloc(sizeof(nsIAbSyncListener *) * mListenerArrayCount);
if (!mListenerArray)
return NS_ERROR_OUT_OF_MEMORY;
nsCRT::memset(mListenerArray, 0, (sizeof(nsIAbSyncListener *) * mListenerArrayCount));
mListenerArray[0] = aListener;
NS_ADDREF(mListenerArray[0]);
return NS_OK;
}
}
/* void RemoveSyncListener (in nsIAbSyncListener aListener); */
NS_IMETHODIMP nsAbSync::RemoveSyncListener(nsIAbSyncListener *aListener)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] == aListener)
{
NS_RELEASE(mListenerArray[i]);
mListenerArray[i] = nsnull;
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
nsresult
nsAbSync::DeleteListeners()
{
if ( (mListenerArray) && (*mListenerArray) )
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
{
NS_RELEASE(mListenerArray[i]);
}
PR_FREEIF(mListenerArray);
}
mListenerArrayCount = 0;
return NS_OK;
}
nsresult
nsAbSync::NotifyListenersOnStartSync(PRInt32 aTransactionID, PRUint32 aMsgSize)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnStartOperation(aTransactionID, aMsgSize);
return NS_OK;
}
nsresult
nsAbSync::NotifyListenersOnProgress(PRInt32 aTransactionID, PRUint32 aProgress, PRUint32 aProgressMax)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnProgress(aTransactionID, aProgress, aProgressMax);
return NS_OK;
}
nsresult
nsAbSync::NotifyListenersOnStatus(PRInt32 aTransactionID, const PRUnichar *aMsg)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnStatus(aTransactionID, aMsg);
return NS_OK;
}
nsresult
nsAbSync::NotifyListenersOnStopSync(PRInt32 aTransactionID, nsresult aStatus,
const PRUnichar *aMsg)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnStopOperation(aTransactionID, aStatus, aMsg);
return NS_OK;
}
/* void OnStartOperation (in PRInt32 aTransactionID, in PRUint32 aMsgSize); */
NS_IMETHODIMP nsAbSync::OnStartOperation(PRInt32 aTransactionID, PRUint32 aMsgSize)
{
NotifyListenersOnStartSync(aTransactionID, aMsgSize);
return NS_OK;
}
/* void OnProgress (in PRInt32 aTransactionID, in PRUint32 aProgress, in PRUint32 aProgressMax); */
NS_IMETHODIMP nsAbSync::OnProgress(PRInt32 aTransactionID, PRUint32 aProgress, PRUint32 aProgressMax)
{
NotifyListenersOnProgress(aTransactionID, aProgress, aProgressMax);
return NS_OK;
}
/* void OnStatus (in PRInt32 aTransactionID, in wstring aMsg); */
NS_IMETHODIMP nsAbSync::OnStatus(PRInt32 aTransactionID, const PRUnichar *aMsg)
{
NotifyListenersOnStatus(aTransactionID, aMsg);
return NS_OK;
}
/* void OnStopOperation (in PRInt32 aTransactionID, in nsresult aStatus, in wstring aMsg, out string aProtocolResponse); */
NS_IMETHODIMP nsAbSync::OnStopOperation(PRInt32 aTransactionID, nsresult aStatus, const PRUnichar *aMsg, const char *aProtocolResponse)
{
//
// Now, figure out what the server told us to do with the sync operation.
//
if (aProtocolResponse)
ProcessServerResponse(aProtocolResponse);
NotifyListenersOnStopSync(aTransactionID, aStatus, aMsg);
InternalCleanup();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// This is the implementation of the actual sync logic.
//
////////////////////////////////////////////////////////////////////////////////////////
/* PRInt32 GetCurrentState (); */
NS_IMETHODIMP nsAbSync::GetCurrentState(PRInt32 *_retval)
{
*_retval = mCurrentState;
return NS_OK;
}
/* void PerformAbSync (out PRInt32 aTransactionID); */
NS_IMETHODIMP nsAbSync::PerformAbSync(PRInt32 *aTransactionID)
{
nsresult rv;
char *postSpec = nsnull;
char *protocolRequest = nsnull;
// If we are already running...don't let anything new start...
if (mCurrentState != nsIAbSyncState::nsIAbSyncIdle)
return NS_ERROR_FAILURE;
// Ok, now get the server/port number we should be hitting with
// this request as well as the local address book we will be
// syncing with...
//
NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
if (NS_FAILED(rv) || !prefs)
return NS_ERROR_FAILURE;
mAbSyncPort = 5000;
prefs->CopyCharPref("mail.absync.server", &mAbSyncServer);
prefs->GetIntPref ("mail.absync.port", &mAbSyncPort);
prefs->CopyCharPref("mail.absync.address_book", &mAbSyncAddressBook);
// Did we get sane values...
if (!mAbSyncServer)
{
rv = NS_ERROR_FAILURE;
goto EarlyExit;
}
postSpec = PR_smprintf("http://%s:%d", mAbSyncServer, mAbSyncPort);
if (!postSpec)
{
rv = NS_ERROR_OUT_OF_MEMORY;
goto EarlyExit;
}
// Ok, we need to see if a particular address book was in the prefs
// If not, then we will use the default, but if there was one specified,
// we need to do a prefs lookup and get the file name of interest
// The pref format is: user_pref("ldap_2.servers.Richie.filename", "abook-1.mab");
//
if ( (mAbSyncAddressBook) && (*mAbSyncAddressBook) )
{
nsCString prefId = "ldap_2.servers.";
prefId.Append(mAbSyncAddressBook);
prefId.Append(".filename");
prefs->CopyCharPref(prefId, &mAbSyncAddressBookFileName);
}
mTransactionID++;
// First, analyze the situation locally and build up a string that we
// will need to post.
//
rv = AnalyzeTheLocalAddressBook();
if (NS_FAILED(rv))
goto EarlyExit;
//
// if we have nothing in mPostString, then we can just return OK...no
// sync was needed
//
if (mPostString == "")
{
rv = NS_OK;
OnStopOperation(mTransactionID, NS_OK, nsnull, nsnull);
goto EarlyExit;
}
// We can keep this object around for reuse...
if (!mPostEngine)
{
rv = nsComponentManager::CreateInstance(kCAbSyncPostEngineCID, NULL, NS_GET_IID(nsIAbSyncPostEngine), getter_AddRefs(mPostEngine));
if ( NS_FAILED(rv) || (!mPostEngine) )
return NS_ERROR_FAILURE;
mPostEngine->AddPostListener((nsIAbSyncPostListener *)this);
}
protocolRequest = mPostString.ToNewCString();
if (!protocolRequest)
goto EarlyExit;
// Ok, FIRE!
rv = mPostEngine->SendAbRequest(postSpec, protocolRequest, mTransactionID);
if (NS_SUCCEEDED(rv))
mCurrentState = nsIAbSyncState::nsIAbSyncRunning;
EarlyExit:
PR_FREEIF(protocolRequest);
PR_FREEIF(postSpec);
if (NS_FAILED(rv))
InternalCleanup();
return rv;
}
NS_IMETHODIMP
nsAbSync::OpenAB(char *aAbName, nsIAddrDatabase **aDatabase)
{
if (!aDatabase)
return NS_ERROR_FAILURE;
nsresult rv = NS_OK;
nsFileSpec* dbPath = nsnull;
NS_WITH_SERVICE(nsIAddrBookSession, abSession, kAddrBookSessionCID, &rv);
if(NS_SUCCEEDED(rv))
abSession->GetUserProfileDirectory(&dbPath);
if (dbPath)
{
if (!aAbName)
(*dbPath) += "abook.mab";
else
(*dbPath) += aAbName;
NS_WITH_SERVICE(nsIAddrDatabase, addrDBFactory, kAddressBookDBCID, &rv);
if (NS_SUCCEEDED(rv) && addrDBFactory)
rv = addrDBFactory->Open(dbPath, PR_TRUE, getter_AddRefs(aDatabase), PR_TRUE);
}
else
rv = NS_ERROR_FAILURE;
return rv;
}
NS_IMETHODIMP
nsAbSync::GenerateProtocolForCard(nsIAbCard *aCard, PRInt32 id, nsString &protLine)
{
PRUnichar *aName = nsnull;
for (PRInt32 i=0; i<kMaxColumns; i++)
{
if (NS_SUCCEEDED(aCard->GetCardValue(mSchemaMappingList[0].abField, &aName)) && (aName) && (*aName))
{
protLine.Append("&");
protLine.Append(mSchemaMappingList[0].serverField);
if (id >= 0)
{
char *tVal = PR_smprintf("%d", id);
if (tVal)
{
protLine.Append(tVal);
nsCRT::free(tVal);
}
}
protLine.Append("=");
protLine.Append(aName);
}
}
return NS_OK;
}
long
GetCRC(char *str)
{
cm_t crcModel;
p_cm_t p = &crcModel;
/*
Name : Crc-32
Width : 32
Poly : 04C11DB7
Init : FFFFFFFF
RefIn : True
RefOut : True
XorOut : FFFFFFFF
Check : CBF43926
*/
p->cm_width = 32;
p->cm_poly = 0x4C11DB7;
p->cm_init = 0xFFFFFFFF;
p->cm_refin = TRUE;
p->cm_refot = TRUE;
p->cm_xorot = 0xFFFFFFFF;
char *pChar = str;
cm_ini( p);
for (PRUint32 i = 0; i < nsCRT::strlen(str); i++, pChar++)
cm_nxt( p, *pChar);
return( cm_crc( p) );
}
PRBool
nsAbSync::ThisCardHasChanged(nsIAbCard *aCard, syncMappingRecord *newSyncRecord, nsString &protLine)
{
syncMappingRecord *historyRecord = nsnull;
PRUint32 counter = 0;
nsString tempProtocolLine = "";
// First, null out the protocol return line
protLine = "";
// Use the localID for this entry to lookup the old history record in the
// cached array
//
if (mOldSyncMapingTable)
{
while (counter < mOldTableSize)
{
if (mOldSyncMapingTable[counter]->localID == newSyncRecord->localID)
{
historyRecord = mOldSyncMapingTable[counter];
break;
}
counter++;
}
}
//
// Now, build up the compare protocol line for this entry.
//
if (NS_FAILED(GenerateProtocolForCard(aCard, -1, tempProtocolLine)))
return PR_FALSE;
// Get the CRC for this temp entry line...
char *tLine = tempProtocolLine.ToNewCString();
if (!tLine)
return PR_FALSE;
newSyncRecord->CRC = GetCRC(tLine);
nsCRT::free(tLine);
//
// #define SYNC_MODIFIED 0x0001 // Must modify record on server
// #define SYNC_ADD 0x0002 // Must add record to server
// #define SYNC_DELETED 0x0004 // Must delete record from server
// #define SYNC_RETRY 0x0008 // Sent to server but failed...must retry!
// #define SYNC_RENUMBER 0x0010 // Renumber on the server
//
// If we have a history record, we need to carry over old items!
if (historyRecord)
{
newSyncRecord->serverID = historyRecord->serverID;
historyRecord->flags &= SYNC_PROCESSED;
}
// If this is a record that has changed from comparing CRC's, then
// when can generate a line that should be tacked on to the output
// going up to the server
//
if ( (!historyRecord) || (historyRecord->CRC != newSyncRecord->CRC) )
{
mCurrentPostRecord++;
if (NS_FAILED(GenerateProtocolForCard(aCard, mCurrentPostRecord, protLine)))
return PR_FALSE;
else
{
if (!historyRecord)
newSyncRecord->flags &= SYNC_ADD;
else
newSyncRecord->flags &= SYNC_MODIFIED;
return PR_TRUE;
}
}
else // This is the same record as before.
{
return PR_FALSE;
}
return PR_FALSE;
}
NS_IMETHODIMP
nsAbSync::AnalyzeAllRecords(nsIAddrDatabase *aDatabase, nsIAbDirectory *directory)
{
nsresult rv = NS_OK;
nsIEnumerator *cardEnum = nsnull;
nsCOMPtr<nsISupports> obj = nsnull;
PRBool exists = PR_FALSE;
PRUint32 readCount = 0;
PRInt32 readSize = 0;
PRUint32 workCounter = 0;
nsString singleProtocolLine = "";
// Init size vars...
mOldTableSize = 0;
mNewTableSize = 0;
PR_FREEIF(mOldSyncMapingTable);
PR_FREEIF(mNewSyncMapingTable);
mCurrentPostRecord = 1;
//
// First thing we need to do is open the absync.dat file
// to compare against the last sync operation.
//
// we want <profile>/absync.dat
//
NS_WITH_SERVICE(nsIFileLocator, locator, kFileLocatorCID, &rv);
if (NS_FAILED(rv))
return rv;
rv = locator->GetFileLocation(nsSpecialFileSpec::App_MailDirectory50, getter_AddRefs(mHistoryFile));
if (NS_FAILED(rv))
return rv;
rv = mHistoryFile->AppendRelativeUnixPath((const char *)"absync.dat");
NS_ASSERTION(NS_SUCCEEDED(rv),"ab sync: failed to append history filename");
if (NS_FAILED(rv))
{
rv = NS_ERROR_FAILURE;
goto GetOut;
}
// Now see if we actually have an old table to work with?
// If not, this is the first sync operation.
//
//mOldSyncMapingTable = nsnull;
//mNewSyncMapingTable = nsnull;
mHistoryFile->Exists(&exists);
// If the old table exists, then we need to load it up!
if (exists)
{
if (NS_SUCCEEDED(mHistoryFile->GetFileSize(&mOldTableSize)))
{
if (NS_FAILED(mHistoryFile->OpenStreamForReading()))
{
rv = NS_ERROR_OUT_OF_MEMORY;
goto GetOut;
}
mOldSyncMapingTable = (syncMappingRecord **) PR_MALLOC(mOldTableSize);
if (!mOldSyncMapingTable)
{
rv = NS_ERROR_OUT_OF_MEMORY;;
goto GetOut;
}
// Init the memory!
nsCRT::memset(mOldSyncMapingTable, 0, mOldTableSize);
// Now get the number of records in the table size!
mOldTableSize /= sizeof(syncMappingRecord);
// Now read the history file into memory!
while (readCount < mOldTableSize)
{
if (NS_FAILED(mHistoryFile->Read((char **)&(mOldSyncMapingTable[readCount]),
sizeof(syncMappingRecord), &readSize))
|| (readSize != sizeof(syncMappingRecord)))
{
rv = NS_ERROR_OUT_OF_MEMORY;;
goto GetOut;
}
}
}
}
rv = aDatabase->EnumerateCards(directory, &cardEnum);
if (NS_FAILED(rv) || (!cardEnum))
{
rv = NS_ERROR_FAILURE;
goto GetOut;
}
//
// Now create the NEW sync mapping table that we will use for this
// current operation. First, we have to count the total number of
// entries...ugh.
//
cardEnum->First();
do
{
mNewTableSize++;
} while (NS_SUCCEEDED(cardEnum->Next()));
mNewSyncMapingTable = (syncMappingRecord **) PR_MALLOC(mNewTableSize * sizeof(syncMappingRecord));
if (!mNewSyncMapingTable)
{
rv = NS_ERROR_OUT_OF_MEMORY;;
goto GetOut;
}
// Init the memory!
nsCRT::memset(mNewSyncMapingTable, 0, (mNewTableSize * sizeof(syncMappingRecord)) );
rv = NS_OK;
cardEnum->First();
do
{
if (NS_FAILED(cardEnum->CurrentItem(getter_AddRefs(obj))))
break;
else
{
nsCOMPtr<nsIAbCard> card;
card = do_QueryInterface(obj, &rv);
if ( NS_SUCCEEDED(rv) && (card) )
{
// First, we need to fill out the localID for this entry. This should
// be the ID from the local database for this card entry
//
// RICHIE - Need access to the unique ID from Candice.
// mNewSyncMapingTable[workCounter] = card.???
mNewSyncMapingTable[workCounter]->localID = workCounter;
if (ThisCardHasChanged(card, mNewSyncMapingTable[workCounter], singleProtocolLine))
{
// If we get here, we should look at the flags in the mNewSyncMapingTable to see
// what we should add to the protocol header area and then tack on the singleProtcolLine
// we got back from this call.
//
if (mNewSyncMapingTable[workCounter]->flags && SYNC_ADD)
{
mPostString.Append("add:");
mPostString.Append(singleProtocolLine);
}
else if (mNewSyncMapingTable[workCounter]->flags && SYNC_MODIFIED)
{
mPostString.Append("modify:");
mPostString.Append(singleProtocolLine);
}
}
}
}
workCounter++;
} while (NS_SUCCEEDED(cardEnum->Next()));
delete cardEnum;
//
// Now, when we get here, we should go through the old history and see if
// there are records we need to delete since we didn't touch them when comparing
// against the current address book
//
readCount = 0;
while (readCount < mOldTableSize)
{
if (!(mOldSyncMapingTable[readCount]->flags && SYNC_PROCESSED))
{
char *tVal = PR_smprintf("%d", mOldSyncMapingTable[readCount]->serverID);
if (tVal)
{
mCurrentPostRecord++;
mPostString.Append("&op=del&id=");
mPostString.Append(tVal);
nsCRT::free(tVal);
}
}
readCount++;
}
GetOut:
if (mHistoryFile)
mHistoryFile->CloseStream();
mHistoryFile = nsnull;
if (NS_FAILED(rv))
{
mOldTableSize = 0;
mNewTableSize = 0;
PR_FREEIF(mOldSyncMapingTable);
PR_FREEIF(mNewSyncMapingTable);
}
// Ok, get out!
return rv;
}
nsresult
nsAbSync::AnalyzeTheLocalAddressBook()
{
// Time to build the mPostString
//
nsresult rv = NS_OK;
nsIAddrDatabase *aDatabase = nsnull;
// Get the address book entry
nsCOMPtr <nsIRDFResource> resource = nsnull;
nsCOMPtr <nsIAbDirectory> directory = nsnull;
nsIAbCard *urlArgCard;
PRUnichar *workEmail = nsnull;
char *charEmail = nsnull;
PRUnichar *workAb = nsnull;
char *charAb = nsnull;
// Init to null...
mPostString = "";
// Now, open the database...for now, make it the default
rv = OpenAB(mAbSyncAddressBookFileName, &aDatabase);
if (NS_FAILED(rv))
return rv;
// Get the RDF service...
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
if (NS_FAILED(rv))
goto EarlyExit;
// this should not be hardcoded to abook.mab
// RICHIE - this works for any address book...not sure why
rv = rdfService->GetResource("abdirectory://abook.mab", getter_AddRefs(resource));
if (NS_FAILED(rv))
goto EarlyExit;
// query interface
directory = do_QueryInterface(resource, &rv);
if (NS_FAILED(rv))
goto EarlyExit;
// Ok, Now we need to analyze the records in the database against
// the sync history file and see what has changed. If it has changed,
// then we need to create the mPostString protocol stuff to make
// the changes
//
rv = AnalyzeAllRecords(aDatabase, directory);
EarlyExit:
// Database is open...make sure to close it
if (aDatabase)
{
aDatabase->Close(PR_TRUE);
}
NS_IF_RELEASE(aDatabase);
NS_IF_RELEASE(urlArgCard);
PR_FREEIF(charEmail);
PR_FREEIF(charAb);
return rv;
}
//
// This is the response side of getting things back from the server
//
nsresult
nsAbSync::ProcessServerResponse(const char *aProtocolResponse)
{
return NS_OK;
}

View File

@ -0,0 +1,147 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsIAbSync_h__
#define __nsIAbSync_h__
#include "nsIAbSync.h"
#include "nsIAbSyncPostListener.h"
#include "nsIAbSyncPostEngine.h"
#include "nsCOMPtr.h"
#include "nsIAddrDatabase.h"
#include "nsIAbDirectory.h"
#include "nsAbSyncCRCModel.h"
//
// Basic Sync Logic
// Keep a Sync mapping table like:
//
// ServerRecordID - Unique ID for a record provided by the
// UAB server.
// LocalRecordID - Local Unique ID, for mobile devices this
// is assigned by the mobile device.
// CRC - CRC of the record last time we synced.
// Flags - Operation to apply to this record. ADD
// if it's new, MOD if it's been modified,
// RET if it was already sent to the server
// but an error occured, etc.
//
// Step 1:
// When the user begins a sync, run through the local database and update the
// sync mapping table. If the CRC has changed, mark the entry modified, if
// it's a new record, add an entry and mark it new, if a record was deleted,
// mark the entry deleted, etc.
//
// Sync approach - server handles all conflict resolution:
//
// Step 2:
// Using the sync mapping table and the local records database, generate the change
// list to send to the server. Mark any modified or new record with the RET (retry)
// flag.
//
// Step 3:
// Get the response back from the server. Since the communication was successful,
// clear the RET (retry) flag on all records. Then apply the server changes back
// to the local database (updating the CRC's in the process). Save the changes to
// the local database, clear the sync mapping table flags and save the new sync
// mapping table.
//
typedef struct {
PRInt32 serverID;
PRInt32 localID;
ulong CRC;
PRUint32 flags;
} syncMappingRecord;
#define SYNC_MODIFIED 0x0001 // Must modify record on server
#define SYNC_ADD 0x0002 // Must add record to server
#define SYNC_DELETED 0x0004 // Must delete record from server
#define SYNC_RETRY 0x0008 // Sent to server but failed...must retry!
#define SYNC_RENUMBER 0x0010 // Renumber on the server
#define SYNC_PROCESSED 0x8000 // We processed the entry...nothing to do
//
// We need this structure for mapping our field names to the server
// field names
//
#define kMaxColumns 38
typedef struct {
const char *abField;
const char *serverField;
} schemaStruct;
class nsAbSync : public nsIAbSync, public nsIAbSyncPostListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIABSYNC
NS_DECL_NSIABSYNCPOSTLISTENER
nsAbSync();
virtual ~nsAbSync();
/* additional members */
private:
// Handy methods for listeners...
nsresult DeleteListeners();
nsresult NotifyListenersOnStartSync(PRInt32 aTransactionID, const PRUint32 aMsgSize);
nsresult NotifyListenersOnProgress(PRInt32 aTransactionID, PRUint32 aProgress, PRUint32 aProgressMax);
nsresult NotifyListenersOnStatus(PRInt32 aTransactionID, const PRUnichar *aMsg);
nsresult NotifyListenersOnStopSync(PRInt32 aTransactionID, nsresult aStatus, const PRUnichar *aMsg);
nsresult AnalyzeTheLocalAddressBook();
nsresult ProcessServerResponse(const char *aProtocolResponse);
NS_IMETHOD InitSchemaColumns();
NS_IMETHOD OpenAB(char *aAbName, nsIAddrDatabase **aDatabase);
NS_IMETHOD AnalyzeAllRecords(nsIAddrDatabase *aDatabase, nsIAbDirectory *directory);
NS_IMETHOD GenerateProtocolForCard(nsIAbCard *aCard, PRInt32 id, nsString &protLine);
PRBool ThisCardHasChanged(nsIAbCard *aCard, syncMappingRecord *syncRecord, nsString &protLine);
nsresult InternalCleanup();
nsCOMPtr<nsIAbSyncPostEngine> mPostEngine;
nsString mPostString;
nsIAbSyncListener **mListenerArray;
PRInt32 mListenerArrayCount;
PRInt32 mCurrentState;
// Setting for ABSync operations...
char *mAbSyncServer;
PRInt32 mAbSyncPort;
char *mAbSyncAddressBook;
char *mAbSyncAddressBookFileName;
PRInt32 mTransactionID;
PRInt32 mCurrentPostRecord;
nsCOMPtr<nsIFileSpec> mHistoryFile;
PRUint32 mOldTableSize;
syncMappingRecord **mOldSyncMapingTable;
PRUint32 mNewTableSize;
syncMappingRecord **mNewSyncMapingTable;
schemaStruct mSchemaMappingList[kMaxColumns];
};
#endif /* __nsIAbSync_h__ */

View File

@ -0,0 +1,137 @@
/******************************************************************************/
/* Start of crcmodel.c */
/******************************************************************************/
/* */
/* Author : Ross Williams (ross@guest.adelaide.edu.au.). */
/* Date : 3 June 1993. */
/* Status : Public domain. */
/* */
/* Description : This is the implementation (.c) file for the reference */
/* implementation of the Rocksoft^tm Model CRC Algorithm. For more */
/* information on the Rocksoft^tm Model CRC Algorithm, see the document */
/* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */
/* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */
/* "ftp.adelaide.edu.au/pub/rocksoft". */
/* */
/* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */
/* */
/******************************************************************************/
/* */
/* Implementation Notes */
/* -------------------- */
/* To avoid inconsistencies, the specification of each function is not echoed */
/* here. See the header file for a description of these functions. */
/* This package is light on checking because I want to keep it short and */
/* simple and portable (i.e. it would be too messy to distribute my entire */
/* C culture (e.g. assertions package) with this package. */
/* */
/******************************************************************************/
#include "nsAbSyncCRCModel.h"
/******************************************************************************/
/* The following definitions make the code more readable. */
#define BITMASK(X) (1L << (X))
#define MASK32 0xFFFFFFFFL
#define LOCAL static
/******************************************************************************/
LOCAL ulong reflect P_((ulong v,int b));
LOCAL ulong reflect (ulong v, int b)
/* Returns the value v with the bottom b [0,32] bits reflected. */
/* Example: reflect(0x3e23L,3) == 0x3e26 */
{
int i;
ulong t = v;
for (i=0; i<b; i++)
{
if (t & 1L)
v|= BITMASK((b-1)-i);
else
v&= ~BITMASK((b-1)-i);
t>>=1;
}
return v;
}
/******************************************************************************/
LOCAL ulong widmask P_((p_cm_t));
LOCAL ulong widmask (p_cm_t p_cm)
/* Returns a longword whose value is (2^p_cm->cm_width)-1. */
/* The trick is to do this portably (e.g. without doing <<32). */
{
return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L;
}
/******************************************************************************/
void cm_ini (p_cm_t p_cm)
{
p_cm->cm_reg = p_cm->cm_init;
}
/******************************************************************************/
void cm_nxt (p_cm_t p_cm, int ch)
{
int i;
ulong uch = (ulong) ch;
ulong topbit = BITMASK(p_cm->cm_width-1);
if (p_cm->cm_refin) uch = reflect(uch,8);
p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
for (i=0; i<8; i++)
{
if (p_cm->cm_reg & topbit)
p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
else
p_cm->cm_reg <<= 1;
p_cm->cm_reg &= widmask(p_cm);
}
}
/******************************************************************************/
void cm_blk (p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len)
{
while (blk_len--) cm_nxt(p_cm,*blk_adr++);
}
/******************************************************************************/
ulong cm_crc (p_cm_t p_cm)
{
if (p_cm->cm_refot)
return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width);
else
return p_cm->cm_xorot ^ p_cm->cm_reg;
}
/******************************************************************************/
ulong cm_tab (p_cm_t p_cm,int index)
{
int i;
ulong r;
ulong topbit = BITMASK(p_cm->cm_width-1);
ulong inbyte = (ulong) index;
if (p_cm->cm_refin) inbyte = reflect(inbyte,8);
r = inbyte << (p_cm->cm_width-8);
for (i=0; i<8; i++)
if (r & topbit)
r = (r << 1) ^ p_cm->cm_poly;
else
r<<=1;
if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width);
return r & widmask(p_cm);
}
/******************************************************************************/
/* End of crcmodel.c */
/******************************************************************************/

View File

@ -0,0 +1,152 @@
/******************************************************************************/
/* Start of crcmodel.h */
/******************************************************************************/
/* */
/* Author : Ross Williams (ross@guest.adelaide.edu.au.). */
/* Date : 3 June 1993. */
/* Status : Public domain. */
/* */
/* Description : This is the header (.h) file for the reference */
/* implementation of the Rocksoft^tm Model CRC Algorithm. For more */
/* information on the Rocksoft^tm Model CRC Algorithm, see the document */
/* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */
/* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */
/* "ftp.adelaide.edu.au/pub/rocksoft". */
/* */
/* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */
/* */
/******************************************************************************/
/* */
/* How to Use This Package */
/* ----------------------- */
/* Step 1: Declare a variable of type cm_t. Declare another variable */
/* (p_cm say) of type p_cm_t and initialize it to point to the first */
/* variable (e.g. p_cm_t p_cm = &cm_t). */
/* */
/* Step 2: Assign values to the parameter fields of the structure. */
/* If you don't know what to assign, see the document cited earlier. */
/* For example: */
/* p_cm->cm_width = 16; */
/* p_cm->cm_poly = 0x8005L; */
/* p_cm->cm_init = 0L; */
/* p_cm->cm_refin = TRUE; */
/* p_cm->cm_refot = TRUE; */
/* p_cm->cm_xorot = 0L; */
/* Note: Poly is specified without its top bit (18005 becomes 8005). */
/* Note: Width is one bit less than the raw poly width. */
/* */
/* Step 3: Initialize the instance with a call cm_ini(p_cm); */
/* */
/* Step 4: Process zero or more message bytes by placing zero or more */
/* successive calls to cm_nxt. Example: cm_nxt(p_cm,ch); */
/* */
/* Step 5: Extract the CRC value at any time by calling crc = cm_crc(p_cm); */
/* If the CRC is a 16-bit value, it will be in the bottom 16 bits. */
/* */
/******************************************************************************/
/* */
/* Design Notes */
/* ------------ */
/* PORTABILITY: This package has been coded very conservatively so that */
/* it will run on as many machines as possible. For example, all external */
/* identifiers have been restricted to 6 characters and all internal ones to */
/* 8 characters. The prefix cm (for Crc Model) is used as an attempt to avoid */
/* namespace collisions. This package is endian independent. */
/* */
/* EFFICIENCY: This package (and its interface) is not designed for */
/* speed. The purpose of this package is to act as a well-defined reference */
/* model for the specification of CRC algorithms. If you want speed, cook up */
/* a specific table-driven implementation as described in the document cited */
/* above. This package is designed for validation only; if you have found or */
/* implemented a CRC algorithm and wish to describe it as a set of parameters */
/* to the Rocksoft^tm Model CRC Algorithm, your CRC algorithm implementation */
/* should behave identically to this package under those parameters. */
/* */
/******************************************************************************/
/* The following #ifndef encloses this entire */
/* header file, rendering it indempotent. */
#ifndef CM_DONE
#define CM_DONE
/******************************************************************************/
/* The following definitions are extracted from my style header file which */
/* would be cumbersome to distribute with this package. The DONE_STYLE is the */
/* idempotence symbol used in my style header file. */
typedef unsigned long ulong;
typedef unsigned char * p_ubyte_;
#ifndef TRUE
#define FALSE 0
#define TRUE 1
#endif
/* Change to the second definition if you don't have prototypes. */
#define P_(A) A
/* #define P_(A) () */
/* Uncomment this definition if you don't have void. */
/* typedef int void; */
/******************************************************************************/
/* CRC Model Abstract Type */
/* ----------------------- */
/* The following type stores the context of an executing instance of the */
/* model algorithm. Most of the fields are model parameters which must be */
/* set before the first initializing call to cm_ini. */
typedef struct
{
int cm_width; /* Parameter: Width in bits [8,32]. */
ulong cm_poly; /* Parameter: The algorithm's polynomial. */
ulong cm_init; /* Parameter: Initial register value. */
bool cm_refin; /* Parameter: Reflect input bytes? */
bool cm_refot; /* Parameter: Reflect output CRC? */
ulong cm_xorot; /* Parameter: XOR this to output CRC. */
ulong cm_reg; /* Context: Context during execution. */
} cm_t;
typedef cm_t *p_cm_t;
/******************************************************************************/
/* Functions That Implement The Model */
/* ---------------------------------- */
/* The following functions animate the cm_t abstraction. */
void cm_ini P_((p_cm_t p_cm));
/* Initializes the argument CRC model instance. */
/* All parameter fields must be set before calling this. */
void cm_nxt P_((p_cm_t p_cm,int ch));
/* Processes a single message byte [0,255]. */
void cm_blk P_((p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len));
/* Processes a block of message bytes. */
ulong cm_crc P_((p_cm_t p_cm));
/* Returns the CRC value for the message bytes processed so far. */
/******************************************************************************/
/* Functions For Table Calculation */
/* ------------------------------- */
/* The following function can be used to calculate a CRC lookup table. */
/* It can also be used at run-time to create or check static tables. */
ulong cm_tab P_((p_cm_t p_cm,int index));
/* Returns the i'th entry for the lookup table for the specified algorithm. */
/* The function examines the fields cm_width, cm_poly, cm_refin, and the */
/* argument table index in the range [0,255] and returns the table entry in */
/* the bottom cm_width bytes of the return value. */
/******************************************************************************/
/* End of the header file idempotence #ifndef */
#endif
/******************************************************************************/
/* End of crcmodel.h */
/******************************************************************************/

View File

@ -0,0 +1,520 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "msgCore.h" // for pre-compiled headers
#include "nsCOMPtr.h"
#include <stdio.h>
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "comi18n.h"
#include "prmem.h"
#include "plstr.h"
#include "nsRepository.h"
#include "nsIURI.h"
#include "nsString.h"
#include "nsAbSyncPostEngine.h"
#include "nsIIOService.h"
#include "nsIChannel.h"
#include "nsNetUtil.h"
#include "nsMimeTypes.h"
#include "nsIHTTPChannel.h"
#include "nsHTTPEnums.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
/*
* This function will be used by the factory to generate an
* mime object class object....
*/
nsresult NS_NewPostEngine(nsAbSyncPostEngine ** aInstancePtrResult)
{
//nsresult result = NS_OK;
NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr");
if (nsnull != aInstancePtrResult)
{
nsAbSyncPostEngine *obj = new nsAbSyncPostEngine();
if (obj)
return obj->QueryInterface(NS_GET_IID(nsIStreamListener), (void**) aInstancePtrResult);
else
return NS_ERROR_OUT_OF_MEMORY; // we couldn't allocate the object
}
else
return NS_ERROR_NULL_POINTER; // aInstancePtrResult was NULL....
}
NS_IMPL_ADDREF(nsAbSyncPostEngine)
NS_IMPL_RELEASE(nsAbSyncPostEngine)
NS_INTERFACE_MAP_BEGIN(nsAbSyncPostEngine)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIStreamObserver)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIURIContentListener)
NS_INTERFACE_MAP_END
/*
* Inherited methods for nsMimeConverter
*/
nsAbSyncPostEngine::nsAbSyncPostEngine()
{
/* the following macro is used to initialize the ref counting data */
NS_INIT_REFCNT();
// Init member variables...
mTotalWritten = 0;
mStillRunning = PR_TRUE;
mCallback = nsnull;
mContentType = nsnull;
mCharset = nsnull;
mListenerArray = nsnull;
mListenerArrayCount = 0;
mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncPostIdle;
mTransactionID = 0;
}
nsAbSyncPostEngine::~nsAbSyncPostEngine()
{
mStillRunning = PR_FALSE;
PR_FREEIF(mContentType);
PR_FREEIF(mCharset);
DeleteListeners();
}
NS_IMETHODIMP nsAbSyncPostEngine::GetInterface(const nsIID & aIID, void * *aInstancePtr)
{
NS_ENSURE_ARG_POINTER(aInstancePtr);
return QueryInterface(aIID, aInstancePtr);
}
// nsIURIContentListener support
NS_IMETHODIMP
nsAbSyncPostEngine::OnStartURIOpen(nsIURI* aURI,
const char* aWindowTarget, PRBool* aAbortOpen)
{
return NS_OK;
}
NS_IMETHODIMP
nsAbSyncPostEngine::GetProtocolHandler(nsIURI *aURI, nsIProtocolHandler **aProtocolHandler)
{
*aProtocolHandler = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsAbSyncPostEngine::IsPreferred(const char * aContentType,
nsURILoadCommand aCommand,
const char * aWindowTarget,
char ** aDesiredContentType,
PRBool * aCanHandleContent)
{
return CanHandleContent(aContentType, aCommand, aWindowTarget, aDesiredContentType,
aCanHandleContent);
}
NS_IMETHODIMP
nsAbSyncPostEngine::CanHandleContent(const char * aContentType,
nsURILoadCommand aCommand,
const char * aWindowTarget,
char ** aDesiredContentType,
PRBool * aCanHandleContent)
{
if (nsCRT::strcasecmp(aContentType, MESSAGE_RFC822) == 0)
*aDesiredContentType = nsCRT::strdup("text/html");
// since we explicilty loaded the url, we always want to handle it!
*aCanHandleContent = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsAbSyncPostEngine::DoContent(const char * aContentType,
nsURILoadCommand aCommand,
const char * aWindowTarget,
nsIChannel * aOpenedChannel,
nsIStreamListener ** aContentHandler,
PRBool * aAbortProcess)
{
nsresult rv = NS_OK;
if (aAbortProcess)
*aAbortProcess = PR_FALSE;
QueryInterface(NS_GET_IID(nsIStreamListener), (void **) aContentHandler);
return rv;
}
NS_IMETHODIMP
nsAbSyncPostEngine::GetParentContentListener(nsIURIContentListener** aParent)
{
*aParent = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsAbSyncPostEngine::SetParentContentListener(nsIURIContentListener* aParent)
{
return NS_OK;
}
NS_IMETHODIMP
nsAbSyncPostEngine::GetLoadCookie(nsISupports ** aLoadCookie)
{
*aLoadCookie = mLoadCookie;
NS_IF_ADDREF(*aLoadCookie);
return NS_OK;
}
NS_IMETHODIMP
nsAbSyncPostEngine::SetLoadCookie(nsISupports * aLoadCookie)
{
mLoadCookie = aLoadCookie;
return NS_OK;
}
nsresult
nsAbSyncPostEngine::StillRunning(PRBool *running)
{
*running = mStillRunning;
return NS_OK;
}
// Methods for nsIStreamListener...
nsresult
nsAbSyncPostEngine::OnDataAvailable(nsIChannel * aChannel, nsISupports * ctxt, nsIInputStream *aIStream,
PRUint32 sourceOffset, PRUint32 aLength)
{
PRUint32 readLen = aLength;
char *buf = (char *)PR_Malloc(aLength);
if (!buf)
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
// read the data from the input stram...
nsresult rv = aIStream->Read(buf, aLength, &readLen);
if (NS_FAILED(rv)) return rv;
// write to the protocol response buffer...
mProtocolResponse.Append(buf, readLen);
PR_FREEIF(buf);
mTotalWritten += readLen;
NotifyListenersOnProgress(mTransactionID, mTotalWritten, 0);
return NS_OK;
}
// Methods for nsIStreamObserver
nsresult
nsAbSyncPostEngine::OnStartRequest(nsIChannel *aChannel, nsISupports *ctxt)
{
NotifyListenersOnStartSending(mTransactionID, mMessageSize);
return NS_OK;
}
nsresult
nsAbSyncPostEngine::OnStopRequest(nsIChannel *aChannel, nsISupports * /* ctxt */, nsresult aStatus, const PRUnichar* aMsg)
{
#ifdef NS_DEBUG_rhp
printf("nsAbSyncPostEngine::OnStopRequest()\n");
#endif
//
// Now complete the stream!
//
mStillRunning = PR_FALSE;
// Check the content type!
if (aChannel)
{
char *contentType = nsnull;
char *charset = nsnull;
if (NS_SUCCEEDED(aChannel->GetContentType(&contentType)) && contentType)
{
if (PL_strcasecmp(contentType, UNKNOWN_CONTENT_TYPE))
{
mContentType = contentType;
}
}
nsCOMPtr<nsIHTTPChannel> httpChannel = do_QueryInterface(aChannel);
if (httpChannel)
{
if (NS_SUCCEEDED(httpChannel->GetCharset(&charset)) && charset)
{
mCharset = charset;
}
}
}
// Now if there is a callback, we need to call it...
if (mCallback)
mCallback (mURL, aStatus, mContentType, mCharset, mTotalWritten, aMsg, mTagData);
char *tProtResponse = mProtocolResponse.ToNewCString();
NotifyListenersOnStopSending(mTransactionID, aStatus, aMsg, tProtResponse);
PR_FREEIF(tProtResponse);
// Time to return...
return NS_OK;
}
nsresult
nsAbSyncPostEngine::Initialize(nsOutputFileStream *fOut,
nsPostCompletionCallback cb,
void *tagData)
{
if (!fOut)
return NS_ERROR_INVALID_ARG;
if (!fOut->is_open())
return NS_ERROR_FAILURE;
mCallback = cb;
mTagData = tagData;
return NS_OK;
}
nsresult
nsAbSyncPostEngine::FireURLRequest(nsIURI *aURL, nsPostCompletionCallback cb,
void *tagData, const char *postData)
{
nsresult rv;
nsIInputStream *postStream = nsnull;
if (!postData)
return NS_ERROR_INVALID_ARG;
rv = NS_NewPostDataStream(&postStream, PR_FALSE, postData, 0);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIChannel> channel;
NS_ENSURE_SUCCESS(NS_OpenURI(getter_AddRefs(channel), aURL, nsnull), NS_ERROR_FAILURE);
// Tag the post stream onto the channel...
nsCOMPtr<nsIHTTPChannel> httpChannel = do_QueryInterface(channel);
if (!httpChannel)
return NS_ERROR_FAILURE;
mMessageSize = nsCRT::strlen(postData);
httpChannel->SetRequestMethod(HM_POST);
httpChannel->SetPostDataStream(postStream);
// let's try uri dispatching...
nsCOMPtr<nsIURILoader> pURILoader (do_GetService(NS_URI_LOADER_PROGID));
NS_ENSURE_TRUE(pURILoader, NS_ERROR_FAILURE);
nsCOMPtr<nsISupports> openContext;
nsCOMPtr<nsISupports> cntListener (do_QueryInterface(NS_STATIC_CAST(nsIStreamListener *, this)));
rv = pURILoader->OpenURI(channel, nsIURILoader::viewNormal, nsnull /* window target */, cntListener);
mURL = dont_QueryInterface(aURL);
mCallback = cb;
mTagData = tagData;
NS_ADDREF(this);
return NS_OK;
}
/* void AddSyncListener (in nsIAbSyncPostListener aListener); */
NS_IMETHODIMP nsAbSyncPostEngine::AddPostListener(nsIAbSyncPostListener *aListener)
{
if ( (mListenerArrayCount > 0) || mListenerArray )
{
++mListenerArrayCount;
mListenerArray = (nsIAbSyncPostListener **)
PR_Realloc(*mListenerArray, sizeof(nsIAbSyncPostListener *) * mListenerArrayCount);
if (!mListenerArray)
return NS_ERROR_OUT_OF_MEMORY;
else
{
mListenerArray[mListenerArrayCount - 1] = aListener;
return NS_OK;
}
}
else
{
mListenerArrayCount = 1;
mListenerArray = (nsIAbSyncPostListener **) PR_Malloc(sizeof(nsIAbSyncPostListener *) * mListenerArrayCount);
if (!mListenerArray)
return NS_ERROR_OUT_OF_MEMORY;
nsCRT::memset(mListenerArray, 0, (sizeof(nsIAbSyncPostListener *) * mListenerArrayCount));
mListenerArray[0] = aListener;
NS_ADDREF(mListenerArray[0]);
return NS_OK;
}
}
/* void RemoveSyncListener (in nsIAbSyncPostListener aListener); */
NS_IMETHODIMP nsAbSyncPostEngine::RemovePostListener(nsIAbSyncPostListener *aListener)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] == aListener)
{
NS_RELEASE(mListenerArray[i]);
mListenerArray[i] = nsnull;
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
nsresult
nsAbSyncPostEngine::DeleteListeners()
{
if ( (mListenerArray) && (*mListenerArray) )
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
{
NS_RELEASE(mListenerArray[i]);
}
PR_FREEIF(mListenerArray);
}
mListenerArrayCount = 0;
return NS_OK;
}
nsresult
nsAbSyncPostEngine::NotifyListenersOnStartSending(PRInt32 aTransactionID, PRUint32 aMsgSize)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnStartOperation(aTransactionID, aMsgSize);
return NS_OK;
}
nsresult
nsAbSyncPostEngine::NotifyListenersOnProgress(PRInt32 aTransactionID, PRUint32 aProgress, PRUint32 aProgressMax)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnProgress(aTransactionID, aProgress, aProgressMax);
return NS_OK;
}
nsresult
nsAbSyncPostEngine::NotifyListenersOnStatus(PRInt32 aTransactionID, PRUnichar *aMsg)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnStatus(aTransactionID, aMsg);
return NS_OK;
}
nsresult
nsAbSyncPostEngine::NotifyListenersOnStopSending(PRInt32 aTransactionID, nsresult aStatus,
const PRUnichar *aMsg, char *aProtocolResponse)
{
PRInt32 i;
for (i=0; i<mListenerArrayCount; i++)
if (mListenerArray[i] != nsnull)
mListenerArray[i]->OnStopOperation(aTransactionID, aStatus, aMsg, aProtocolResponse);
return NS_OK;
}
// Utility to create a nsIURI object...
extern "C" nsresult
nsMimeNewURI(nsIURI** aInstancePtrResult, const char *aSpec, nsIURI *aBase)
{
nsresult res;
if (nsnull == aInstancePtrResult)
return NS_ERROR_NULL_POINTER;
NS_WITH_SERVICE(nsIIOService, pService, kIOServiceCID, &res);
if (NS_FAILED(res))
return NS_ERROR_FACTORY_NOT_REGISTERED;
return pService->NewURI(aSpec, aBase, aInstancePtrResult);
}
static nsresult
PostDoneCallback(nsIURI* aURL, nsresult aStatus,
const char *aContentType,
const char *aCharset,
PRInt32 totalSize,
const PRUnichar* aMsg, void *tagData)
{
nsAbSyncPostEngine *postEngine = (nsAbSyncPostEngine *) tagData;
if (postEngine)
{
postEngine->mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncPostIdle;
}
return NS_OK;
}
/* PRInt32 GetCurrentState (); */
NS_IMETHODIMP nsAbSyncPostEngine::GetCurrentState(PRInt32 *_retval)
{
*_retval = mPostEngineState;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////////////
//
// This is the implementation of the actual post driver.
//
////////////////////////////////////////////////////////////////////////////////////////
/* void SendAbRequest (in string aProtocolRequest, out PRInt32 aTransactionID); */
NS_IMETHODIMP nsAbSyncPostEngine::SendAbRequest(const char *aSpec, const char *aProtocolRequest, PRInt32 aTransactionID)
{
nsresult rv;
nsIURI *workURI = nsnull;
// Only try if we are not currently busy!
if (mPostEngineState != nsIAbSyncPostEngineState::nsIAbSyncPostIdle)
return NS_ERROR_FAILURE;
mTransactionID = aTransactionID;
mProtocolResponse = "";
mTotalWritten = 0;
rv = nsMimeNewURI(&workURI, aSpec, nsnull);
if (NS_FAILED(rv) || (!workURI))
return NS_ERROR_FAILURE;
rv = FireURLRequest(workURI, PostDoneCallback, this, aProtocolRequest);
mPostEngineState = nsIAbSyncPostEngineState::nsIAbSyncPostRunning;
return rv;
}

View File

@ -0,0 +1,108 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsAbSyncPostEngine_h_
#define nsAbSyncPostEngine_h_
#include "nsCOMPtr.h"
#include "nsIBufferInputStream.h"
#include "nsIStreamListener.h"
#include "nsFileStream.h"
#include "nsIAbSyncPostEngine.h"
#include "nsIInterfaceRequestor.h"
#include "nsCURILoader.h"
#include "nsIURIContentListener.h"
#include "nsIURI.h"
//
// Callback declarations for URL completion
//
// For completion of send/message creation operations...
//
typedef nsresult (*nsPostCompletionCallback ) (nsIURI* aURL, nsresult aStatus,
const char *aContentType,
const char *aCharset,
PRInt32 totalSize, const PRUnichar* aMsg,
void *tagData);
class nsAbSyncPostEngine : public nsIAbSyncPostEngine, public nsIStreamListener, public nsIURIContentListener, public nsIInterfaceRequestor {
public:
nsAbSyncPostEngine();
virtual ~nsAbSyncPostEngine();
/* this macro defines QueryInterface, AddRef and Release for this class */
NS_DECL_ISUPPORTS
NS_DECL_NSIABSYNCPOSTENGINE
//
// This is the output stream where the stream converter will write processed data after
// conversion.
//
NS_IMETHOD StillRunning(PRBool *running);
NS_IMETHOD FireURLRequest(nsIURI *aURL, nsPostCompletionCallback cb,
void *tagData, const char *postData);
NS_IMETHOD Initialize(nsOutputFileStream *fOut,
nsPostCompletionCallback cb,
void *tagData);
// Methods for nsIStreamListener
NS_DECL_NSISTREAMLISTENER
// Methods for nsIStreamObserver
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSIURICONTENTLISTENER
NS_DECL_NSIINTERFACEREQUESTOR
PRInt32 mPostEngineState;
PRInt32 mTransactionID;
private:
// Handy methods for listeners...
nsresult DeleteListeners();
nsresult NotifyListenersOnStartSending(PRInt32 aTransactionID, PRUint32 aMsgSize);
nsresult NotifyListenersOnProgress(PRInt32 aTransactionID, PRUint32 aProgress, PRUint32 aProgressMax);
nsresult NotifyListenersOnStatus(PRInt32 aTransactionID, PRUnichar *aMsg);
nsresult NotifyListenersOnStopSending(PRInt32 aTransactionID, nsresult aStatus,
const PRUnichar *aMsg, char *aProtocolResponse);
PRBool mStillRunning; // Are we still running?
PRInt32 mTotalWritten; // Size counter variable
nsString mProtocolResponse; // Protocol response
nsCOMPtr<nsIURI> mURL; // URL being processed
char *mContentType; // The content type retrieved from the server
char *mCharset; // The charset retrieved from the server
void *mTagData; // Tag data for callback...
nsPostCompletionCallback mCallback; // Callback to call once the file is saved...
nsCOMPtr<nsISupports> mLoadCookie; // load cookie used by the uri loader when we post the url
PRInt32 mMessageSize; // Size of POST request...
nsIAbSyncPostListener **mListenerArray;
PRInt32 mListenerArrayCount;
};
/* this function will be used by the factory to generate an class access object....*/
extern nsresult NS_NewPostEngine(nsAbSyncPostEngine **aInstancePtrResult);
#endif /* nsAbSyncPostEngine_h_ */