diff --git a/mailnews/addrbook/src/Makefile.in b/mailnews/addrbook/src/Makefile.in index 52c236c58be..c3b30b69f16 100644 --- a/mailnews/addrbook/src/Makefile.in +++ b/mailnews/addrbook/src/Makefile.in @@ -135,6 +135,7 @@ endif ifdef MOZ_LDAP_XPCOM REQUIRES += mozldap \ uriloader \ + windowwatcher \ $(NULL) EXPORTS += nsAbLDAPDirectoryQuery.h \ @@ -145,6 +146,8 @@ EXPORTS += nsAbLDAPDirectoryQuery.h \ nsAbLDAPReplicationService.h \ nsAbLDAPReplicationQuery.h \ nsAbLDAPReplicationData.h \ + nsAbLDAPChangeLogQuery.h \ + nsAbLDAPChangeLogData.h \ $(NULL) CPPSRCS += nsAbLDAPDirectory.cpp \ @@ -157,6 +160,8 @@ CPPSRCS += nsAbLDAPDirectory.cpp \ nsAbLDAPReplicationService.cpp \ nsAbLDAPReplicationQuery.cpp \ nsAbLDAPReplicationData.cpp \ + nsAbLDAPChangeLogQuery.cpp \ + nsAbLDAPChangeLogData.cpp \ $(NULL) endif diff --git a/mailnews/addrbook/src/makefile.win b/mailnews/addrbook/src/makefile.win index c817b403e49..e69de29bb2d 100644 --- a/mailnews/addrbook/src/makefile.win +++ b/mailnews/addrbook/src/makefile.win @@ -1,158 +0,0 @@ -#!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= addrbook -REQUIRES = xpcom \ - string \ - rdf \ - rdfutil \ - appshell \ - dom \ - layout \ - widget \ - mork \ - uriloader \ - docshell \ - pref \ - necko \ - locale \ - uconv \ - unicharutil \ - webshell \ - msgbase \ - msgbaseutil \ - mime \ - msgcompo \ - appcomps \ - content \ - mozldap \ - intl \ - layout_xul \ - import \ - $(NULL) - -include <$(DEPTH)\config\config.mak> - -################################################################################ -## exports - -EXPORTS= \ - nsAddressBook.h \ - nsAddrBookSession.h \ - nsAbRDFDataSource.h \ - nsDirectoryDataSource.h \ - nsAbCardProperty.h \ - nsDirPrefs.h \ - nsAddrDatabase.h \ - nsAbDirProperty.h \ - nsAbAutoCompleteSession.h \ - nsAbAddressCollecter.h \ - nsAddbookProtocolHandler.h \ - nsAbMDBDirProperty.h \ - nsAbMDBDirectory.h \ - nsAbMDBCardProperty.h \ - nsAbMDBCard.h \ - nsAbBSDirectory.h \ - nsAbOutlookDirFactory.h \ - nsAbDirFactoryService.h \ - nsAddbookUrl.h \ - nsAbOutlookDirectory.h \ - nsAbOutlookCard.h \ - nsAbMDBDirFactory.h \ - nsAbDirectoryQuery.h \ - nsAbDirectoryQueryProxy.h \ - nsAbDirSearchListener.h \ - nsAbView.h \ -!if !defined(DISABLE_LDAP) - nsAbLDAPDirectoryQuery.h \ - nsAbLDAPDirectory.h \ - nsAbLDAPDirFactory.h \ - nsAbLDAPCard.h \ - nsAbLDAPAutoCompFormatter.h \ - nsAbLDAPReplicationService.h \ - nsAbLDAPReplicationQuery.h \ - nsAbLDAPReplicationData.h \ -!endif - nsAbDirectoryRDFResource.h \ - nsAbBooleanExpression.h \ - $(NULL) - -################################################################################ -## library - -LIBRARY_NAME=addrbook_s - -CPP_OBJS= \ - .\$(OBJDIR)\nsAddressBook.obj \ - .\$(OBJDIR)\nsAddrBookSession.obj \ - .\$(OBJDIR)\nsAbRDFDataSource.obj \ - .\$(OBJDIR)\nsDirectoryDataSource.obj \ - .\$(OBJDIR)\nsAbCardProperty.obj \ - .\$(OBJDIR)\nsDirPrefs.obj \ - .\$(OBJDIR)\nsAddrDatabase.obj \ - .\$(OBJDIR)\nsAbDirProperty.obj \ - .\$(OBJDIR)\nsAbAutoCompleteSession.obj \ - .\$(OBJDIR)\nsAbAddressCollecter.obj \ - .\$(OBJDIR)\nsAddbookProtocolHandler.obj \ - .\$(OBJDIR)\nsAbMDBDirProperty.obj \ - .\$(OBJDIR)\nsAbMDBDirectory.obj \ - .\$(OBJDIR)\nsAbMDBCardProperty.obj \ - .\$(OBJDIR)\nsAbMDBCard.obj \ - .\$(OBJDIR)\nsAbBSDirectory.obj \ - .\$(OBJDIR)\nsAddbookUrl.obj \ - .\$(OBJDIR)\nsAbDirFactoryService.obj \ - .\$(OBJDIR)\nsAbMDBDirFactory.obj \ - .\$(OBJDIR)\nsAbOutlookDirectory.obj \ - .\$(OBJDIR)\nsAbOutlookCard.obj \ - .\$(OBJDIR)\nsAbOutlookDirFactory.obj \ - .\$(OBJDIR)\nsMapiAddressBook.obj \ - .\$(OBJDIR)\nsAbUtils.obj \ - .\$(OBJDIR)\nsAbDirectoryQuery.obj \ - .\$(OBJDIR)\nsAbDirectoryQueryProxy.obj \ - .\$(OBJDIR)\nsAbDirSearchListener.obj \ - .\$(OBJDIR)\nsAbView.obj \ -!if !defined(DISABLE_LDAP) - .\$(OBJDIR)\nsAbLDAPDirectory.obj \ - .\$(OBJDIR)\nsAbLDAPDirFactory.obj \ - .\$(OBJDIR)\nsAbLDAPCard.obj \ - .\$(OBJDIR)\nsAbLDAPProperties.obj \ - .\$(OBJDIR)\nsAbLDAPDirectoryQuery.obj \ - .\$(OBJDIR)\nsAbBoolExprToLDAPFilter.obj \ - .\$(OBJDIR)\nsAbLDAPAutoCompFormatter.obj \ - .\$(OBJDIR)\nsAbLDAPReplicationService.obj \ - .\$(OBJDIR)\nsAbLDAPReplicationQuery.obj \ - .\$(OBJDIR)\nsAbLDAPReplicationData.obj \ -!endif - .\$(OBJDIR)\nsAbBooleanExpression.obj \ - .\$(OBJDIR)\nsAbDirectoryRDFResource.obj \ - .\$(OBJDIR)\nsAbQueryStringToExpression.obj \ - .\$(OBJDIR)\nsAbWinHelper.obj \ - .\$(OBJDIR)\nsWabAddressBook.obj \ - $(NULL) - -include <$(DEPTH)\config\rules.mak> - -libs:: $(LIBRARY) - $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib - -clobber:: - rm -f $(DIST)\lib\$(LIBRARY_NAME).lib diff --git a/mailnews/addrbook/src/nsAbLDAPChangeLogData.cpp b/mailnews/addrbook/src/nsAbLDAPChangeLogData.cpp new file mode 100644 index 00000000000..c79f7a96cc3 --- /dev/null +++ b/mailnews/addrbook/src/nsAbLDAPChangeLogData.cpp @@ -0,0 +1,554 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Rajiv Dayal + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsAbLDAPChangeLogData.h" +#include "nsAbLDAPChangeLogQuery.h" +#include "nsLDAP.h" +#include "nsIAbCard.h" +#include "nsIAddrBookSession.h" +#include "nsAbBaseCID.h" +#include "nsAbUtils.h" +#include "nsAbMDBCard.h" +#include "nsAbLDAPCard.h" +#include "nsFileSpec.h" +#include "nsAbLDAPProperties.h" +#include "nsProxiedService.h" +#include "nsAutoLock.h" +#include "nsIAuthPrompt.h" +#include "nsIStringBundle.h" +#include "nsIWindowWatcher.h" +#include "nsUnicharUtils.h" + +// defined here since to be used +// only locally to this file. +enum UpdateOp { + NO_OP, + ENTRY_ADD, + ENTRY_DELETE, + ENTRY_MODIFY +}; + +nsAbLDAPProcessChangeLogData::nsAbLDAPProcessChangeLogData() +: mUseChangeLog(PR_FALSE), + mEntriesAddedQueryCount(0), + mChangeLogEntriesCount(0) +{ + mRootDSEEntry.firstChangeNumber = 0; + mRootDSEEntry.lastChangeNumber = 0; +} + +nsAbLDAPProcessChangeLogData::~nsAbLDAPProcessChangeLogData() +{ + +} + +NS_IMETHODIMP nsAbLDAPProcessChangeLogData::Init(nsIAbLDAPReplicationQuery * query, nsIWebProgressListener *progressListener) +{ + NS_ENSURE_ARG_POINTER(query); + + // here we are assuming that the caller will pass a nsAbLDAPChangeLogQuery object, + // an implementation derived from the implementation of nsIAbLDAPReplicationQuery. + nsresult rv = NS_OK; + mChangeLogQuery = do_QueryInterface(query, &rv); + if(NS_FAILED(rv)) + return rv; + + // call the parent's Init now + return nsAbLDAPProcessReplicationData::Init(query, progressListener); +} + +nsresult nsAbLDAPProcessChangeLogData::OnLDAPBind(nsILDAPMessage *aMessage) +{ + NS_ENSURE_ARG_POINTER(aMessage); + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + PRInt32 errCode; + + nsresult rv = aMessage->GetErrorCode(&errCode); + if(NS_FAILED(rv)) { + Done(PR_FALSE); + return rv; + } + + if(errCode != nsILDAPErrors::SUCCESS) { + Done(PR_FALSE); + return NS_ERROR_FAILURE; + } + + switch(mState) { + case kAnonymousBinding : + rv = GetAuthData(); + if(NS_SUCCEEDED(rv)) + rv = mChangeLogQuery->QueryAuthDN(mAuthUserID); + if(NS_SUCCEEDED(rv)) + mState = kSearchingAuthDN; + break; + case kAuthenticatedBinding : + rv = mChangeLogQuery->QueryRootDSE(); + if(NS_SUCCEEDED(rv)) + mState = kSearchingRootDSE; + break; + } //end of switch + + if(NS_FAILED(rv)) + Abort(); + + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::OnLDAPSearchEntry(nsILDAPMessage *aMessage) +{ + NS_ENSURE_ARG_POINTER(aMessage); + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = NS_OK; + + switch(mState) + { + case kSearchingAuthDN : + { + nsXPIDLString authDN; + rv = aMessage->GetDn(getter_Copies(authDN)); + if(NS_SUCCEEDED(rv) && !authDN.IsEmpty()) + mAuthDN = authDN.get(); + } + break; + case kSearchingRootDSE: + rv = ParseRootDSEEntry(aMessage); + break; + case kFindingChanges: + rv = ParseChangeLogEntries(aMessage); + break; + // fall through since we only add (for updates we delete and add) + case kReplicatingChanges: + case kReplicatingAll : + return nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(aMessage); + } + + if(NS_FAILED(rv)) + Abort(); + + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::OnLDAPSearchResult(nsILDAPMessage *aMessage) +{ + NS_ENSURE_ARG_POINTER(aMessage); + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + PRInt32 errorCode; + + nsresult rv = aMessage->GetErrorCode(&errorCode); + + if(NS_SUCCEEDED(rv)) + { + if(errorCode == nsILDAPErrors::SUCCESS || errorCode == nsILDAPErrors::SIZELIMIT_EXCEEDED) { + switch(mState) { + case kSearchingAuthDN : + rv = OnSearchAuthDNDone(); + break; + case kSearchingRootDSE: + { + // before starting the changeLog check the DB file, if its not there or bogus + // we need to create a new one and set to all. + nsCOMPtr abSession = do_GetService(NS_ADDRBOOKSESSION_CONTRACTID, &rv); + if(NS_FAILED(rv)) + break; + nsFileSpec* dbPath; + rv = abSession->GetUserProfileDirectory(&dbPath); + if(NS_FAILED(rv)) + break; + (*dbPath) += mDirServerInfo->replInfo->fileName; + if (!dbPath->Exists() || !dbPath->GetFileSize()) + mUseChangeLog = PR_FALSE; + delete dbPath; + + // open / create the AB here since it calls Done, + // just return from here. + if (mUseChangeLog) + rv = OpenABForReplicatedDir(PR_FALSE); + else + rv = OpenABForReplicatedDir(PR_TRUE); + if (NS_FAILED(rv)) + return rv; + + // now start the appropriate query + rv = OnSearchRootDSEDone(); + break; + } + case kFindingChanges: + rv = OnFindingChangesDone(); + // if success we return from here since + // this changes state to kReplicatingChanges + // and it falls thru into the if clause below. + if (NS_SUCCEEDED(rv)) + return rv; + break; + case kReplicatingAll : + return nsAbLDAPProcessReplicationData::OnLDAPSearchResult(aMessage); + } // end of switch + } + else + rv = NS_ERROR_FAILURE; + // if one of the changed entry in changelog is not found, + // continue with replicating the next one. + if(mState == kReplicatingChanges) + rv = OnReplicatingChangeDone(); + } // end of outer if + + if(NS_FAILED(rv)) + Abort(); + + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::GetAuthData() +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); + if (!wwatch) + return NS_ERROR_FAILURE; + + nsCOMPtr dialog; + nsresult rv = wwatch->GetNewAuthPrompter(0, getter_AddRefs(dialog)); + if (NS_FAILED(rv)) + return rv; + if (!dialog) + return NS_ERROR_FAILURE; + + nsCOMPtr url; + rv = mQuery->GetReplicationURL(getter_AddRefs(url)); + if (NS_FAILED(rv)) + return rv; + + nsCAutoString serverUri; + rv = url->GetSpec(serverUri); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + if (NS_FAILED (rv)) + return rv ; + nsCOMPtr bundle; + rv = bundleService->CreateBundle("chrome://messenger/locale/addressbook/addressBook.properties", getter_AddRefs(bundle)); + if (NS_FAILED (rv)) + return rv ; + + nsXPIDLString title; + rv = bundle->GetStringFromName(NS_LITERAL_STRING("AuthDlgTitle").get(), getter_Copies(title)); + if (NS_FAILED (rv)) + return rv ; + + nsXPIDLString desc; + rv = bundle->GetStringFromName(NS_LITERAL_STRING("AuthDlgDesc").get(), getter_Copies(desc)); + if (NS_FAILED (rv)) + return rv ; + + nsXPIDLString username; + nsXPIDLString password; + PRBool btnResult = PR_FALSE; + rv = dialog->PromptUsernameAndPassword(title, desc, + NS_ConvertUTF8toUCS2(serverUri).get(), + nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY, + getter_Copies(username), getter_Copies(password), + &btnResult); + if(NS_SUCCEEDED(rv) && btnResult) { + mAuthUserID = username; + mAuthPswd = password; + mDirServerInfo->enableAuth=PR_TRUE; + mDirServerInfo->savePassword=PR_TRUE; + } + else + rv = NS_ERROR_FAILURE; + + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::OnSearchAuthDNDone() +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr url; + nsresult rv = mQuery->GetReplicationURL(getter_AddRefs(url)); + if(NS_SUCCEEDED(rv)) + rv = mQuery->ConnectToLDAPServer(url, mAuthDN); + if(NS_SUCCEEDED(rv)) { + mState = kAuthenticatedBinding; + PR_FREEIF(mDirServerInfo->authDn); + mDirServerInfo->authDn=ToNewCString(NS_ConvertUCS2toUTF8(mAuthDN)); + } + + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::ParseRootDSEEntry(nsILDAPMessage *aMessage) +{ + NS_ENSURE_ARG_POINTER(aMessage); + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + // populate the RootDSEChangeLogEntry + CharPtrArrayGuard attrs; + nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr()); + // no attributes !!! + if(NS_FAILED(rv)) + return rv; + + for(PRInt32 i=attrs.GetSize()-1; i >= 0; i--) { + PRUnicharPtrArrayGuard vals; + rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr()); + if(NS_FAILED(rv)) + continue; + if(vals.GetSize()) { + if (!PL_strcasecmp(attrs[i], "changelog")) + mRootDSEEntry.changeLogDN = vals[0]; + if (!PL_strcasecmp(attrs[i], "firstChangeNumber")) + mRootDSEEntry.firstChangeNumber = atol(NS_LossyConvertUCS2toASCII(vals[0]).get()); + if (!PL_strcasecmp(attrs[i], "lastChangeNumber")) + mRootDSEEntry.lastChangeNumber = atol(NS_LossyConvertUCS2toASCII(vals[0]).get()); + if (!PL_strcasecmp(attrs[i], "dataVersion")) + mRootDSEEntry.dataVersion = NS_ConvertUCS2toUTF8(vals[0]).get(); + } + } + + if((mRootDSEEntry.lastChangeNumber > 0) + && (mDirServerInfo->replInfo->lastChangeNumber < mRootDSEEntry.lastChangeNumber) + && (mDirServerInfo->replInfo->lastChangeNumber > mRootDSEEntry.firstChangeNumber) + ) + mUseChangeLog = PR_TRUE; + + if(mRootDSEEntry.lastChangeNumber && (mDirServerInfo->replInfo->lastChangeNumber == mRootDSEEntry.lastChangeNumber)) { + Done(PR_TRUE); // we are up to date no need to replicate, db not open yet so call Done + return NS_OK; + } + + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::OnSearchRootDSEDone() +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = NS_OK; + + if(mUseChangeLog) { + rv = mChangeLogQuery->QueryChangeLog(mRootDSEEntry.changeLogDN, mRootDSEEntry.lastChangeNumber); + if (NS_FAILED(rv)) + return rv; + mState = kFindingChanges; + if(mListener) + mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_FALSE); + } + else { + rv = mQuery->QueryAllEntries(); + if (NS_FAILED(rv)) + return rv; + mState = kReplicatingAll; + if(mListener) + mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_TRUE); + } + + mDirServerInfo->replInfo->lastChangeNumber = mRootDSEEntry.lastChangeNumber; + PR_FREEIF(mDirServerInfo->replInfo->dataVersion); + mDirServerInfo->replInfo->dataVersion = ToNewCString(mRootDSEEntry.dataVersion); + + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::ParseChangeLogEntries(nsILDAPMessage *aMessage) +{ + NS_ENSURE_ARG_POINTER(aMessage); + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + // populate the RootDSEChangeLogEntry + CharPtrArrayGuard attrs; + nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr()); + // no attributes + if(NS_FAILED(rv)) + return rv; + + nsAutoString targetDN; + UpdateOp operation = NO_OP; + for(PRInt32 i = attrs.GetSize()-1; i >= 0; i--) { + PRUnicharPtrArrayGuard vals; + rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr()); + if(NS_FAILED(rv)) + continue; + if(vals.GetSize()) { + if (!PL_strcasecmp(attrs[i], "targetdn")) + targetDN = vals[0]; + if (!PL_strcasecmp(attrs[i], "changetype")) { + if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("add"), nsCaseInsensitiveStringComparator())) + operation = ENTRY_ADD; + if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("modify"), nsCaseInsensitiveStringComparator())) + operation = ENTRY_MODIFY; + if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("delete"), nsCaseInsensitiveStringComparator())) + operation = ENTRY_DELETE; + } + } + } + + mChangeLogEntriesCount++; + if(!(mChangeLogEntriesCount % 10)) { // inform the listener every 10 entries + mListener->OnProgressChange(nsnull,nsnull,mChangeLogEntriesCount, -1, mChangeLogEntriesCount, -1); + // in case if the LDAP Connection thread is starved and causes problem + // uncomment this one and try. + // PR_Sleep(PR_INTERVAL_NO_WAIT); // give others a chance + } + +#ifdef DEBUG_rdayal + printf ("ChangeLog Replication : Updated Entry : %s for OpType : %u\n", + NS_ConvertUCS2toUTF8(targetDN).get(), operation); +#endif + + switch(operation) { + case ENTRY_ADD: + // add the DN to the add list if not already in the list + if(!(mEntriesToAdd.IndexOf(targetDN) >= 0)) + mEntriesToAdd.AppendString(targetDN); + break; + case ENTRY_DELETE: + // donot check the return here since delete may fail if + // entry deleted in changelog doesnot exist in DB + // for e.g if the user specifies a filter, so go next entry + DeleteCard(targetDN); + break; + case ENTRY_MODIFY: + // for modify, delte the entry from DB and add updated entry + // we do this since we cannot access the changes attribs of changelog + rv = DeleteCard(targetDN); + if (NS_SUCCEEDED(rv)) + if(!(mEntriesToAdd.IndexOf(targetDN) >= 0)) + mEntriesToAdd.AppendString(targetDN); + break; + default: + // should not come here, would come here only + // if the entry is not a changeLog entry + NS_WARNING("nsAbLDAPProcessChangeLogData::ParseChangeLogEntries" + "Not an changelog entry"); + } + + // go ahead processing the next entry, a modify or delete DB operation + // can 'correctly' fail if the entry is not present in the DB. + // eg : in case a filter is specified. + return NS_OK; +} + +nsresult nsAbLDAPProcessChangeLogData::OnFindingChangesDone() +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + +#ifdef DEBUG_rdayal + printf ("ChangeLog Replication : Finding Changes Done \n"); +#endif + + nsresult rv = NS_OK; + + // no entries to add/update (for updates too we delete and add) entries, + // we took care of deletes in ParseChangeLogEntries, all Done! + mEntriesAddedQueryCount = mEntriesToAdd.Count(); + if(mEntriesAddedQueryCount <= 0) { + if(mReplicationDB && mDBOpen) { + // close the DB, no need to commit since we have not made + // any changes yet to the DB. + rv = mReplicationDB->Close(PR_FALSE); + NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB Close(no commit) on Success failed"); + mDBOpen = PR_FALSE; + // once are done with the replication file, delete the backup file + if(mBackupReplicationFile) { + rv = mBackupReplicationFile->Remove(PR_FALSE); + NS_ASSERTION(NS_SUCCEEDED(rv), "Replication BackupFile Remove on Success failed"); + } + } + Done(PR_TRUE); + return NS_OK; + } + + // decrement the count first to get the correct array element + mEntriesAddedQueryCount--; + rv = mChangeLogQuery->QueryChangedEntries(*(mEntriesToAdd[mEntriesAddedQueryCount])); + if (NS_FAILED(rv)) + return rv; + + if(mListener && NS_SUCCEEDED(rv)) + mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_TRUE); + + mState = kReplicatingChanges; + return rv; +} + +nsresult nsAbLDAPProcessChangeLogData::OnReplicatingChangeDone() +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = NS_OK; + + if(!mEntriesAddedQueryCount) + { + if(mReplicationDB && mDBOpen) { + rv = mReplicationDB->Close(PR_TRUE); // commit and close the DB + NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB Close (commit) on Success failed"); + mDBOpen = PR_FALSE; + } + // once we done with the replication file, delete the backup file + if(mBackupReplicationFile) { + rv = mBackupReplicationFile->Remove(PR_FALSE); + NS_ASSERTION(NS_SUCCEEDED(rv), "Replication BackupFile Remove on Success failed"); + } + Done(PR_TRUE); // all data is recieved + return NS_OK; + } + + // remove the entry already added from the list and query the next one + if(mEntriesAddedQueryCount < mEntriesToAdd.Count() && mEntriesAddedQueryCount >= 0) + mEntriesToAdd.RemoveStringAt(mEntriesAddedQueryCount); + mEntriesAddedQueryCount--; + rv = mChangeLogQuery->QueryChangedEntries(*(mEntriesToAdd[mEntriesAddedQueryCount])); + + return rv; +} + diff --git a/mailnews/addrbook/src/nsAbLDAPChangeLogData.h b/mailnews/addrbook/src/nsAbLDAPChangeLogData.h new file mode 100644 index 00000000000..df402a1864e --- /dev/null +++ b/mailnews/addrbook/src/nsAbLDAPChangeLogData.h @@ -0,0 +1,90 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Rajiv Dayal + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsAbLDAPChangeLogData_h__ +#define nsAbLDAPChangeLogData_h__ + +#include "nsAbLDAPReplicationData.h" +#include "nsAbLDAPChangeLogQuery.h" +#include "nsVoidArray.h" + +typedef struct { + nsString changeLogDN; + PRInt32 firstChangeNumber; + PRInt32 lastChangeNumber; + nsCString dataVersion; +} RootDSEChangeLogEntry; + +class nsAbLDAPProcessChangeLogData : public nsAbLDAPProcessReplicationData +{ +public : + + nsAbLDAPProcessChangeLogData(); + ~nsAbLDAPProcessChangeLogData(); + + NS_IMETHOD Init(nsIAbLDAPReplicationQuery * query, nsIWebProgressListener *progressListener); + +protected : + + nsCOMPtr mChangeLogQuery; + + nsresult OnLDAPBind(nsILDAPMessage *aMessage); + nsresult OnLDAPSearchEntry(nsILDAPMessage *aMessage); + nsresult OnLDAPSearchResult(nsILDAPMessage *aMessage); + + nsresult ParseChangeLogEntries(nsILDAPMessage *aMessage); + nsresult ParseRootDSEEntry(nsILDAPMessage *aMessage); + + nsresult GetAuthData(); // displays username and password prompt + nsString mAuthUserID; // user id of the user making the connection + + nsresult OnSearchAuthDNDone(); + nsresult OnSearchRootDSEDone(); + nsresult OnFindingChangesDone(); + nsresult OnReplicatingChangeDone(); + + RootDSEChangeLogEntry mRootDSEEntry; + PRBool mUseChangeLog; + PRInt32 mChangeLogEntriesCount; + + PRInt32 mEntriesAddedQueryCount; + nsStringArray mEntriesToAdd; +}; + + +#endif // nsAbLDAPChangeLogData_h__ + diff --git a/mailnews/addrbook/src/nsAbLDAPChangeLogQuery.cpp b/mailnews/addrbook/src/nsAbLDAPChangeLogQuery.cpp new file mode 100644 index 00000000000..bf45fc6eaa2 --- /dev/null +++ b/mailnews/addrbook/src/nsAbLDAPChangeLogQuery.cpp @@ -0,0 +1,191 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Rajiv Dayal + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsCOMPtr.h" +#include "nsAbLDAPChangeLogQuery.h" +#include "nsAbLDAPReplicationService.h" +#include "nsAbLDAPChangeLogData.h" +#include "nsAbLDAPProperties.h" +#include "nsAutoLock.h" +#include "nsAbUtils.h" +#include "prprf.h" +#include "nsDirPrefs.h" +#include "nsAbBaseCID.h" +#include "nsPrintfCString.h" + + +NS_IMPL_ISUPPORTS_INHERITED1(nsAbLDAPChangeLogQuery, nsAbLDAPReplicationQuery, nsIAbLDAPChangeLogQuery) + +nsAbLDAPChangeLogQuery::nsAbLDAPChangeLogQuery() +{ + NS_INIT_ISUPPORTS(); +} + +nsAbLDAPChangeLogQuery::~nsAbLDAPChangeLogQuery() +{ + +} + +// this is to be defined only till this is not hooked to SSL to get authDN and authPswd +#define USE_AUTHDLG + +NS_IMETHODIMP nsAbLDAPChangeLogQuery::Init(const nsACString & aPrefName, nsIWebProgressListener *aProgressListener) +{ + if(aPrefName.IsEmpty()) + return NS_ERROR_UNEXPECTED; + + mDirPrefName = aPrefName; + + nsresult rv = InitLDAPData(); + if(NS_FAILED(rv)) + return rv; + + // create the ChangeLog Data Processor + mDataProcessor = do_CreateInstance(NS_ABLDAP_PROCESSCHANGELOGDATA_CONTRACTID, &rv); + if(NS_FAILED(rv)) + return rv; + + // 'this' initialized + mInitialized = PR_TRUE; + + return mDataProcessor->Init(this, aProgressListener); +} + +NS_IMETHODIMP nsAbLDAPChangeLogQuery::DoReplicationQuery() +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + +#ifdef USE_AUTHDLG + return ConnectToLDAPServer(mURL, NS_LITERAL_STRING("")); +#else + mDataProcessor->PopulateAuthData(); + return ConnectToLDAPServer(mURL, mAuthDN); +#endif +} + +NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryAuthDN(const nsAString & aValueUsedToFindDn) +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = NS_OK; + + CharPtrArrayGuard attributes; + *attributes.GetSizeAddr() = 2; + *attributes.GetArrayAddr() = NS_STATIC_CAST(char **, nsMemory::Alloc((*attributes.GetSizeAddr()) * sizeof(char *))); + attributes.GetArray()[0] = ToNewCString(nsDependentCString(DIR_GetFirstAttributeString(mDirServer, cn))); + attributes.GetArray()[1] = nsnull; + + nsAutoString filter; + filter.AssignWithConversion(DIR_GetFirstAttributeString(mDirServer, auth)); + filter.AppendWithConversion(NS_LITERAL_CSTRING("=").get()); + filter += aValueUsedToFindDn; + + nsXPIDLCString dn; + rv = mURL->GetDn(getter_Copies(dn)); + if(NS_FAILED(rv)) + return rv; + + return mOperation->SearchExt(NS_ConvertUTF8toUCS2(dn).get(), nsILDAPURL::SCOPE_SUBTREE, + filter.get(), + attributes.GetSize(), attributes.GetArray(), + 0, 0); +} + +NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryRootDSE() +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + return mOperation->SearchExt(nsnull, nsILDAPURL::SCOPE_BASE, + NS_LITERAL_STRING("objectclass=*").get(), + MozillaLdapPropertyRelator::rootDSEAttribCount, + MozillaLdapPropertyRelator::changeLogRootDSEAttribs, + 0, 0); +} + +NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryChangeLog(const nsAString & aChangeLogDN, PRInt32 aLastChangeNo) +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + if(aChangeLogDN.IsEmpty()) + return NS_ERROR_UNEXPECTED; + + // make sure that the filter here just have one condition + // and should not be enclosed in enclosing brackets. + // also condition '>' doesnot work, it should be '>='/ + nsCAutoString filter (NS_LITERAL_CSTRING("changenumber>=")); + filter.AppendInt(mDirServer->replInfo->lastChangeNumber+1); + + return mOperation->SearchExt(PromiseFlatString(aChangeLogDN).get(), + nsILDAPURL::SCOPE_ONELEVEL, + NS_ConvertUTF8toUCS2(filter).get(), + MozillaLdapPropertyRelator::changeLogEntryAttribCount, + MozillaLdapPropertyRelator::changeLogEntryAttribs, + 0, 0); +} + +NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryChangedEntries(const nsAString & aChangedEntryDN) +{ + if(!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + if(aChangedEntryDN.IsEmpty()) + return NS_ERROR_UNEXPECTED; + + nsXPIDLCString urlFilter; + nsresult rv = mURL->GetFilter(getter_Copies(urlFilter)); + if(NS_FAILED(rv)) + return rv; + + PRInt32 scope; + rv = mURL->GetScope(&scope); + if(NS_FAILED(rv)) + return rv; + + CharPtrArrayGuard attributes; + rv = mURL->GetAttributes(attributes.GetSizeAddr(), attributes.GetArrayAddr()); + if(NS_FAILED(rv)) + return rv; + + return mOperation->SearchExt(PromiseFlatString(aChangedEntryDN).get(), scope, + NS_ConvertUTF8toUCS2(urlFilter).get(), + attributes.GetSize(), attributes.GetArray(), + 0, 0); +} + diff --git a/mailnews/addrbook/src/nsAbLDAPChangeLogQuery.h b/mailnews/addrbook/src/nsAbLDAPChangeLogQuery.h new file mode 100644 index 00000000000..9d007a2cc57 --- /dev/null +++ b/mailnews/addrbook/src/nsAbLDAPChangeLogQuery.h @@ -0,0 +1,59 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Rajiv Dayal + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsAbLDAPChangeLogQuery_h__ +#define nsAbLDAPChangeLogQuery_h__ + +#include "nsAbLDAPReplicationQuery.h" +#include "nsString.h" + +class nsAbLDAPChangeLogQuery : public nsIAbLDAPChangeLogQuery, + public nsAbLDAPReplicationQuery +{ +public : + NS_DECL_ISUPPORTS + NS_DECL_NSIABLDAPCHANGELOGQUERY + + nsAbLDAPChangeLogQuery(); + virtual ~nsAbLDAPChangeLogQuery(); + + NS_IMETHOD DoReplicationQuery(); + NS_IMETHOD Init(const nsACString & aPrefName, nsIWebProgressListener *aProgressListener); +}; + + +#endif // nsAbLDAPChangeLogQuery_h__ diff --git a/mailnews/addrbook/src/nsAbLDAPProperties.cpp b/mailnews/addrbook/src/nsAbLDAPProperties.cpp index 8abca52bda8..89ffb267d66 100644 --- a/mailnews/addrbook/src/nsAbLDAPProperties.cpp +++ b/mailnews/addrbook/src/nsAbLDAPProperties.cpp @@ -44,6 +44,7 @@ #include "nsString.h" #include "nsReadableUtils.h" + /* Table defining the relationship between mozilla card properties and corresponding @@ -180,6 +181,24 @@ static MozillaLdapPropertyRelation mozillaLdapPropertyTable[] = const MozillaLdapPropertyRelation* MozillaLdapPropertyRelator::table = mozillaLdapPropertyTable; const int MozillaLdapPropertyRelator::tableSize = sizeof (mozillaLdapPropertyTable) / sizeof (MozillaLdapPropertyRelation); +static const char * sLDAPChangeLogRootDSEAttribs[] = +{ + "changelog", + "firstChangeNumber", + "lastChangeNumber", + "dataVersion" +}; +static const char * sLDAPChangeLogEntryAttribs[] = +{ + "targetdn", + "changetype" +}; + +const char ** MozillaLdapPropertyRelator::changeLogRootDSEAttribs = sLDAPChangeLogRootDSEAttribs; +const int MozillaLdapPropertyRelator::rootDSEAttribCount = sizeof(sLDAPChangeLogRootDSEAttribs)/sizeof(char**); +const char ** MozillaLdapPropertyRelator::changeLogEntryAttribs = sLDAPChangeLogEntryAttribs; +const int MozillaLdapPropertyRelator::changeLogEntryAttribCount = sizeof(sLDAPChangeLogEntryAttribs)/sizeof(char**); + PRBool MozillaLdapPropertyRelator::IsInitialized = PR_FALSE ; nsHashtable MozillaLdapPropertyRelator::mMozillaToLdap; nsHashtable MozillaLdapPropertyRelator::mLdapToMozilla; @@ -198,6 +217,7 @@ void MozillaLdapPropertyRelator::Initialize(void) IsInitialized = PR_TRUE; } + nsresult MozillaLdapPropertyRelator::GetAllSupportedLDAPAttributes(nsCString &aResult) { if (tableSize < 1) @@ -268,4 +288,3 @@ nsresult MozillaLdapPropertyRelator::createCardPropertyFromLDAPMessage (nsILDAPM return rv; } - diff --git a/mailnews/addrbook/src/nsAbLDAPProperties.h b/mailnews/addrbook/src/nsAbLDAPProperties.h index f14cfc5ba45..e194782e779 100644 --- a/mailnews/addrbook/src/nsAbLDAPProperties.h +++ b/mailnews/addrbook/src/nsAbLDAPProperties.h @@ -71,6 +71,12 @@ public: static nsHashtable mMozillaToLdap ; static PRBool IsInitialized; + static const char ** changeLogRootDSEAttribs; + static const char ** changeLogEntryAttribs; + + static const int rootDSEAttribCount; + static const int changeLogEntryAttribCount; + public: static const MozillaLdapPropertyRelation* findMozillaPropertyFromLdap (const char* ldapProperty); static const MozillaLdapPropertyRelation* findLdapPropertyFromMozilla (const char* mozillaProperty); diff --git a/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp b/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp index ef88e4baac1..d5f238b73c6 100644 --- a/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp +++ b/mailnews/addrbook/src/nsAbLDAPReplicationData.cpp @@ -48,19 +48,24 @@ #include "nsAbLDAPProperties.h" #include "nsAbLDAPReplicationQuery.h" #include "nsProxiedService.h" +#include "nsCPasswordManager.h" +#include "nsIRDFService.h" +#include "nsIRDFResource.h" +// once bug # 101252 gets fixed, this should be reverted back to be non threadsafe +// implementation is not really thread safe since each object should exist +// independently along with its related independent nsAbLDAPReplicationQuery object. NS_IMPL_THREADSAFE_ISUPPORTS2(nsAbLDAPProcessReplicationData, nsIAbLDAPProcessReplicationData, nsILDAPMessageListener) nsAbLDAPProcessReplicationData::nsAbLDAPProcessReplicationData() - : mState(kQueryNotStarted), + : mState(kIdle), mProtocol(-1), mCount(0), - mReplInfo(nsnull), + mDirServerInfo(nsnull), mInitialized(PR_FALSE), mDBOpen(PR_FALSE) { NS_INIT_ISUPPORTS(); - /* member initializers and constructor code */ } nsAbLDAPProcessReplicationData::~nsAbLDAPProcessReplicationData() @@ -74,16 +79,14 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Init(nsIAbLDAPReplicationQuery *qu { NS_ENSURE_ARG_POINTER(query); - nsresult rv = NS_OK; - mQuery = query; - rv = mQuery->GetReplicationInfo(&mReplInfo); + nsresult rv = mQuery->GetReplicationServerInfo(&mDirServerInfo); if(NS_FAILED(rv)) { mQuery = nsnull; return rv; } - if(!mReplInfo) { + if(!mDirServerInfo) { mQuery = nsnull; return NS_ERROR_FAILURE; } @@ -106,7 +109,6 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::GetReplicationState(PRInt32 *aRepl NS_IMETHODIMP nsAbLDAPProcessReplicationData::GetProtocolUsed(PRInt32 *aProtocolUsed) { NS_ENSURE_ARG_POINTER(aProtocolUsed); - *aProtocolUsed = mProtocol; return NS_OK; } @@ -116,16 +118,14 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPInit(nsresult aStatus) if(!mInitialized) return NS_ERROR_NOT_INITIALIZED; - nsresult rv = NS_OK; - // Make sure that the Init() worked properly if(NS_FAILED(aStatus)) { Done(PR_FALSE); - return rv; + return NS_ERROR_FAILURE; } nsCOMPtr listener; - rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, + nsresult rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, NS_GET_IID(nsILDAPMessageListener), NS_STATIC_CAST(nsILDAPMessageListener*, this), PROXY_SYNC | PROXY_ALWAYS, @@ -156,10 +156,17 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPInit(nsresult aStatus) } // Bind + if(mAuthPswd.IsEmpty()) { rv = operation->SimpleBind(nsnull); + mState = kAnonymousBinding; + } + else { + rv = operation->SimpleBind(mAuthPswd.get()); + mState = kAuthenticatedBinding; + } + if(NS_FAILED(rv)) { Done(PR_FALSE); - return rv; } return rv; @@ -171,10 +178,8 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::OnLDAPMessage(nsILDAPMessage *aMes if(!mInitialized) return NS_ERROR_NOT_INITIALIZED; - nsresult rv = NS_OK; - PRInt32 messageType; - rv = aMessage->GetType(&messageType); + nsresult rv = aMessage->GetType(&messageType); if(NS_FAILED(rv)) { #ifdef DEBUG_rdayal printf("LDAP Replication : OnLDAPMessage : couldnot GetType \n"); @@ -208,15 +213,17 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Abort() if(!mInitialized) return NS_ERROR_NOT_INITIALIZED; - nsresult rv = NS_OK; +#ifdef DEBUG_rdayal + printf ("ChangeLog Replication : ABORT called !!! \n"); +#endif nsCOMPtr operation; - rv = mQuery->GetOperation(getter_AddRefs(operation)); - if(operation && mState != kQueryNotStarted) + nsresult rv = mQuery->GetOperation(getter_AddRefs(operation)); + if(operation && mState != kIdle) { rv = operation->Abandon(); if(NS_SUCCEEDED(rv)) - mState = kQueryNotStarted; + mState = kIdle; } if(mReplicationDB && mDBOpen) { @@ -228,8 +235,8 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Abort() rv = mReplicationFile->Remove(PR_FALSE); if(NS_SUCCEEDED(rv)) { // now put back the backed up replicated file if aborted - if(mBackupReplicationFile) - rv = mBackupReplicationFile->MoveTo(nsnull, mReplInfo->fileName); + if(mBackupReplicationFile && mDirServerInfo->replInfo) + rv = mBackupReplicationFile->MoveTo(nsnull, mDirServerInfo->replInfo->fileName); } } } @@ -240,6 +247,41 @@ NS_IMETHODIMP nsAbLDAPProcessReplicationData::Abort() return rv; } +// this should get the authDN from prefs and password from PswdMgr +NS_IMETHODIMP nsAbLDAPProcessReplicationData::PopulateAuthData() +{ + mAuthDN.AssignWithConversion(mDirServerInfo->authDn); + + nsresult rv = NS_OK; + nsCOMPtr passwordMgrInt = do_GetService(NS_PASSWORDMANAGER_CONTRACTID, &rv); + if(NS_SUCCEEDED(rv) && passwordMgrInt) { + // Get the current server URI + nsCOMPtr url; + rv = mQuery->GetReplicationURL(getter_AddRefs(url)); + if (NS_FAILED(rv)) + return rv; + nsCAutoString serverUri; + rv = url->GetSpec(serverUri); + if (NS_FAILED(rv)) + return rv; + + nsCAutoString hostFound; + nsAutoString userNameFound; + nsAutoString passwordFound; + + // Get password entry corresponding to the server URI we are passing in. + rv = passwordMgrInt->FindPasswordEntry(serverUri, NS_LITERAL_STRING(""), NS_LITERAL_STRING(""), + hostFound, userNameFound, passwordFound); + if (NS_FAILED(rv)) + return rv; + + if (!passwordFound.IsEmpty()) + mAuthPswd = passwordFound; + } + + return rv; +} + nsresult nsAbLDAPProcessReplicationData::OnLDAPBind(nsILDAPMessage *aMessage) { NS_ENSURE_ARG_POINTER(aMessage); @@ -259,9 +301,9 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPBind(nsILDAPMessage *aMessage) return NS_ERROR_FAILURE; } - rv = CreateABForReplicatedDir(); + rv = OpenABForReplicatedDir(PR_TRUE); if(NS_FAILED(rv)) { - // do not call Done here since CreateABForReplicationDir calls it. + // do not call done here since it is called by OpenABForReplicationDir return rv; } @@ -289,14 +331,10 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess if(!mReplicationDB || !mDBOpen) return NS_ERROR_FAILURE; - nsresult rv; - - nsAbLDAPCard card; - - PRBool hasSetCardProperty = PR_FALSE; - rv = MozillaLdapPropertyRelator::createCardPropertyFromLDAPMessage(aMessage, + + nsresult rv = MozillaLdapPropertyRelator::createCardPropertyFromLDAPMessage(aMessage, &card, &hasSetCardProperty); if(NS_FAILED(rv)) { Abort(); @@ -305,11 +343,12 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess if(hasSetCardProperty == PR_FALSE) { - Abort(); - return NS_ERROR_FAILURE; + NS_WARNING("nsAbLDAPProcessReplicationData::OnLDAPSearchEntry" + "No card Properties found and set"); + // if some entries are bogus for us, continue with next one + return NS_OK; } - #ifdef DEBUG_rdayal nsXPIDLString firstName; rv = card.GetFirstName(getter_Copies(firstName)); @@ -324,7 +363,6 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess printf("\n LDAPReplication :: got card #: %d, name: %s \n", mCount, name.get()); #endif - nsCOMPtr dbCard; dbCard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv); if(NS_FAILED(rv)) { @@ -351,6 +389,28 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(nsILDAPMessage *aMess return rv; } + // now set the attribute for the DN of the entry in the card in the DB + nsXPIDLString authDN; + rv = aMessage->GetDn(getter_Copies(authDN)); + if(NS_SUCCEEDED(rv) && !authDN.IsEmpty()) + { + dbCard->SetAbDatabase(mReplicationDB); + dbCard->SetStringAttribute("_DN", authDN.get()); + } + + newCard = do_QueryInterface(dbCard, &rv); + if(NS_FAILED(rv)) { + Abort(); + return rv; + } + + rv = mReplicationDB->EditCard(newCard, PR_FALSE); + if(NS_FAILED(rv)) { + Abort(); + return rv; + } + + mCount ++; if(!(mCount % 10)) // inform the listener every 10 entries @@ -375,9 +435,8 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchResult(nsILDAPMessage *aMes if(!mInitialized) return NS_ERROR_NOT_INITIALIZED; - nsresult rv = NS_OK; PRInt32 errorCode; - rv = aMessage->GetErrorCode(&errorCode); + nsresult rv = aMessage->GetErrorCode(&errorCode); if(NS_SUCCEEDED(rv)) { // We are done with the LDAP search for all entries. @@ -411,9 +470,9 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchResult(nsILDAPMessage *aMes NS_ASSERTION(NS_SUCCEEDED(rv), "Replication File Remove on Failure failed"); if(NS_SUCCEEDED(rv)) { // now put back the backed up replicated file - if(mBackupReplicationFile) + if(mBackupReplicationFile && mDirServerInfo->replInfo) { - rv = mBackupReplicationFile->MoveTo(nsnull, mReplInfo->fileName); + rv = mBackupReplicationFile->MoveTo(nsnull, mDirServerInfo->replInfo->fileName); NS_ASSERTION(NS_SUCCEEDED(rv), "Replication Backup File Move back on Failure failed"); } } @@ -424,7 +483,7 @@ nsresult nsAbLDAPProcessReplicationData::OnLDAPSearchResult(nsILDAPMessage *aMes return NS_OK; } -nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir() +nsresult nsAbLDAPProcessReplicationData::OpenABForReplicatedDir(PRBool aCreate) { if(!mInitialized) return NS_ERROR_NOT_INITIALIZED; @@ -437,7 +496,7 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir() return rv; } - if(!mReplInfo->fileName) { + if(!mDirServerInfo->replInfo->fileName) { Done(PR_FALSE); return NS_ERROR_FAILURE; } @@ -449,7 +508,7 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir() return rv; } - (*dbPath) += mReplInfo->fileName; + (*dbPath) += mDirServerInfo->replInfo->fileName; // if the AB DB already exists backup existing one, // in case if the user cancels or Abort put back the backed up file @@ -461,10 +520,12 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir() Done(PR_FALSE); return rv; } - // create the backup file object same as replication file object + // create the backup file object same as the Replication file object. // we create a backup file here since we need to cleanup the existing file - // and then commit so instead of deleting existing cards we just clone the - // existing one for a much better performance. + // for create and then commit so instead of deleting existing cards we just + // clone the existing one for a much better performance - for Download All. + // And also important in case if replication fails we donot lose user's existing + // replicated data for both Download all and Changelog. rv = mReplicationFile->Clone(getter_AddRefs(mBackupReplicationFile)); if(NS_FAILED(rv)) { delete dbPath; @@ -477,16 +538,43 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir() Done(PR_FALSE); return rv; } - nsXPIDLCString backupFilePath; - rv = mBackupReplicationFile->GetLeafName(getter_Copies(backupFilePath)); + nsXPIDLCString backupFileLeafName; + rv = mBackupReplicationFile->GetLeafName(getter_Copies(backupFileLeafName)); + if(NS_FAILED(rv)) { + delete dbPath; + Done(PR_FALSE); + return rv; + } + // remove the newly created unique backup file so that move and copy succeeds. + rv = mBackupReplicationFile->Remove(PR_FALSE); if(NS_FAILED(rv)) { delete dbPath; Done(PR_FALSE); return rv; } - rv = mBackupReplicationFile->MoveTo(nsnull, backupFilePath.get()); - // this will take care of all failed cases for moving to backup file above + if(aCreate) { + // set backup file to existing replication file for move + mBackupReplicationFile->SetLeafName(mDirServerInfo->replInfo->fileName); + rv = mBackupReplicationFile->MoveTo(nsnull, backupFileLeafName.get()); + // set the backup file leaf name now + if (NS_SUCCEEDED(rv)) + mBackupReplicationFile->SetLeafName(backupFileLeafName.get()); + } + else { + // set backup file to existing replication file for copy + mBackupReplicationFile->SetLeafName(mDirServerInfo->replInfo->fileName); + // specify the parent here specifically, + // passing nsnull to copy to the same dir actually renames existing file + // instead of making another copy of the existing file. + nsCOMPtr parent; + rv = mBackupReplicationFile->GetParent(getter_AddRefs(parent)); + if (NS_SUCCEEDED(rv)) + rv = mBackupReplicationFile->CopyTo(parent, backupFileLeafName.get()); + // set the backup file leaf name now + if (NS_SUCCEEDED(rv)) + mBackupReplicationFile->SetLeafName(backupFileLeafName.get()); + } if(NS_FAILED(rv)) { delete dbPath; Done(PR_FALSE); @@ -498,14 +586,18 @@ nsresult nsAbLDAPProcessReplicationData::CreateABForReplicatedDir() do_GetService(NS_ADDRDATABASE_CONTRACTID, &rv); if(NS_FAILED(rv)) { delete dbPath; + if (mBackupReplicationFile) + mBackupReplicationFile->Remove(PR_FALSE); Done(PR_FALSE); return rv; } - rv = addrDBFactory->Open(dbPath, PR_TRUE, getter_AddRefs(mReplicationDB), PR_TRUE); + rv = addrDBFactory->Open(dbPath, aCreate, getter_AddRefs(mReplicationDB), PR_TRUE); delete dbPath; if(NS_FAILED(rv)) { Done(PR_FALSE); + if (mBackupReplicationFile) + mBackupReplicationFile->Remove(PR_FALSE); return rv; } @@ -518,6 +610,8 @@ void nsAbLDAPProcessReplicationData::Done(PRBool aSuccess) if(!mInitialized) return; + mState = kReplicationDone; + mQuery->Done(aSuccess); if(mListener) @@ -527,3 +621,11 @@ void nsAbLDAPProcessReplicationData::Done(PRBool aSuccess) // releas the query now. mQuery = nsnull; } + +nsresult nsAbLDAPProcessReplicationData::DeleteCard(nsString & aDn) +{ + nsCOMPtr cardToDelete; + mReplicationDB->GetCardFromAttribute(nsnull, "_DN", NS_ConvertUCS2toUTF8(aDn).get(), + PR_FALSE, getter_AddRefs(cardToDelete)); + return mReplicationDB->DeleteCard(cardToDelete, PR_FALSE); +} diff --git a/mailnews/addrbook/src/nsAbLDAPReplicationData.h b/mailnews/addrbook/src/nsAbLDAPReplicationData.h index c26d1cff346..50f44138518 100644 --- a/mailnews/addrbook/src/nsAbLDAPReplicationData.h +++ b/mailnews/addrbook/src/nsAbLDAPReplicationData.h @@ -72,13 +72,16 @@ protected : PRBool mDBOpen; PRBool mInitialized; - DIR_ReplicationInfo * mReplInfo; + DIR_Server * mDirServerInfo; + nsString mAuthDN; // authDN of the user + nsString mAuthPswd; // pswd of the authDN user virtual nsresult OnLDAPBind(nsILDAPMessage *aMessage); virtual nsresult OnLDAPSearchEntry(nsILDAPMessage *aMessage); virtual nsresult OnLDAPSearchResult(nsILDAPMessage *aMessage); - nsresult CreateABForReplicatedDir(); + nsresult OpenABForReplicatedDir(PRBool bCreate); + nsresult DeleteCard(nsString & aDn); void Done(PRBool aSuccess); }; diff --git a/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp b/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp index 18394125806..1992c6c121c 100644 --- a/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp +++ b/mailnews/addrbook/src/nsAbLDAPReplicationQuery.cpp @@ -56,7 +56,6 @@ nsAbLDAPReplicationQuery::nsAbLDAPReplicationQuery() mInitialized(PR_FALSE) { NS_INIT_ISUPPORTS(); - /* member initializers and constructor code */ } nsAbLDAPReplicationQuery::~nsAbLDAPReplicationQuery() @@ -77,9 +76,15 @@ nsresult nsAbLDAPReplicationQuery::InitLDAPData() // this is done here to take care of the problem related to bug # 99124. // earlier versions of Mozilla could have the fileName associated with the directory // to be abook.mab which is the profile's personal addressbook. If the pref points to - // it generate a new filename and set it as the replication filename. - if (!nsCRT::strcasecmp(mDirServer->fileName,kPersonalAddressbook) || !mDirServer->fileName) - DIR_SetServerFileName(mDirServer, mDirServer->serverName); + // it, calls nsDirPrefs to generate a new server filename. + if (!nsCRT::strcasecmp(mDirServer->fileName,kPersonalAddressbook) + || !mDirServer->fileName || !(*mDirServer->fileName)) { + // initialize mDirServer->filename is null or else DIR_SetServerFileName doesnot work + // and no point in passing the 2nd param (leafName) to it as it doesnot use that. + PR_FREEIF(mDirServer->fileName); + mDirServer->fileName=nsnull; + DIR_SetServerFileName (mDirServer, nsnull); + } // use the dir server filename for replication PR_FREEIF(mDirServer->replInfo->fileName); // since DeleteServer frees the replInfo->fileName make a copy of string @@ -105,15 +110,14 @@ nsresult nsAbLDAPReplicationQuery::InitLDAPData() return rv; } -nsresult nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL * aURL) +NS_IMETHODIMP nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL *aURL, const nsAString & aAuthDN) { + NS_ENSURE_ARG_POINTER(aURL); if (!mInitialized) return NS_ERROR_NOT_INITIALIZED; - nsresult rv = NS_OK; - nsCAutoString host; - rv = aURL->GetHost(host); + nsresult rv = aURL->GetHost(host); if (NS_FAILED(rv)) return rv; if (host.IsEmpty()) @@ -126,13 +130,6 @@ nsresult nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL * aURL) if (!port) return NS_ERROR_UNEXPECTED; - nsXPIDLCString dn; - rv = aURL->GetDn(getter_Copies(dn)); - if (NS_FAILED(rv)) - return rv; - if (dn.IsEmpty()) - return NS_ERROR_UNEXPECTED; - // Initiate LDAP message listener to the current thread nsCOMPtr listener; rv = NS_GetProxyForObject(NS_CURRENT_EVENTQ, @@ -143,8 +140,26 @@ nsresult nsAbLDAPReplicationQuery::ConnectToLDAPServer(nsILDAPURL * aURL) if (!listener) return NS_ERROR_FAILURE; + // this could be a rebind call + PRInt32 replicationState = nsIAbLDAPProcessReplicationData::kIdle; + rv = mDataProcessor->GetReplicationState(&replicationState); + if(NS_FAILED(rv)) + return rv; + if((replicationState != nsIAbLDAPProcessReplicationData::kIdle)) + { + // release old and create a new instance + mConnection = do_CreateInstance(NS_LDAPCONNECTION_CONTRACTID, &rv); + if(NS_FAILED(rv)) + return rv; + + // release old and create a new instance + mOperation = do_CreateInstance(NS_LDAPOPERATION_CONTRACTID, &rv); + if(NS_FAILED(rv)) + return rv; + } + // initialize the LDAP connection - return mConnection->Init(host.get(), port, NS_ConvertUTF8toUCS2(dn).get(), listener); + return mConnection->Init(host.get(), port, PromiseFlatString(aAuthDN).get(), listener); } NS_IMETHODIMP nsAbLDAPReplicationQuery::Init(const nsACString & aPrefName, nsIWebProgressListener *aProgressListener) @@ -154,9 +169,7 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::Init(const nsACString & aPrefName, nsIWe mDirPrefName = aPrefName; - nsresult rv = NS_OK; - - rv = InitLDAPData(); + nsresult rv = InitLDAPData(); if (NS_FAILED(rv)) return rv; @@ -172,7 +185,7 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::Init(const nsACString & aPrefName, nsIWe NS_IMETHODIMP nsAbLDAPReplicationQuery::DoReplicationQuery() { - return ConnectToLDAPServer(mURL); + return ConnectToLDAPServer(mURL, NS_LITERAL_STRING("")); } NS_IMETHODIMP nsAbLDAPReplicationQuery::QueryAllEntries() @@ -180,12 +193,10 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::QueryAllEntries() if (!mInitialized) return NS_ERROR_NOT_INITIALIZED; - nsresult rv = NS_OK; - // get the search filter associated with the directory server url; // nsXPIDLCString urlFilter; - rv = mURL->GetFilter(getter_Copies(urlFilter)); + nsresult rv = mURL->GetFilter(getter_Copies(urlFilter)); if (NS_FAILED(rv)) return rv; @@ -231,6 +242,9 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::Done(PRBool aSuccess) if (NS_SUCCEEDED(rv)) replicationService->Done(aSuccess); + if (aSuccess) + DIR_SavePrefsForOneServer(mDirServer); + return rv; } @@ -268,13 +282,14 @@ NS_IMETHODIMP nsAbLDAPReplicationQuery::GetReplicationURL(nsILDAPURL * *aReplica return NS_OK; } -NS_IMETHODIMP nsAbLDAPReplicationQuery::GetReplicationInfo(DIR_ReplicationInfo * *aReplicationInfo) +NS_IMETHODIMP nsAbLDAPReplicationQuery::GetReplicationServerInfo(DIR_Server * *aReplicationServerInfo) { - NS_ENSURE_ARG_POINTER(aReplicationInfo); + NS_ENSURE_ARG_POINTER(aReplicationServerInfo); if (!mInitialized) return NS_ERROR_NOT_INITIALIZED; - *aReplicationInfo = mDirServer->replInfo; + *aReplicationServerInfo = mDirServer; return NS_OK; } + diff --git a/mailnews/addrbook/src/nsAbLDAPReplicationQuery.h b/mailnews/addrbook/src/nsAbLDAPReplicationQuery.h index 96cc1c0deb6..59e605e5125 100644 --- a/mailnews/addrbook/src/nsAbLDAPReplicationQuery.h +++ b/mailnews/addrbook/src/nsAbLDAPReplicationQuery.h @@ -58,7 +58,6 @@ public: virtual ~nsAbLDAPReplicationQuery(); nsresult InitLDAPData(); - nsresult ConnectToLDAPServer(nsILDAPURL * aURL); protected : // pointer to interfaces used by this object diff --git a/mailnews/addrbook/src/nsAbLDAPReplicationService.cpp b/mailnews/addrbook/src/nsAbLDAPReplicationService.cpp index a41b894039d..118ce7f6da0 100644 --- a/mailnews/addrbook/src/nsAbLDAPReplicationService.cpp +++ b/mailnews/addrbook/src/nsAbLDAPReplicationService.cpp @@ -42,9 +42,12 @@ #include "nsAbBaseCID.h" #include "nsIWebProgressListener.h" +#include "nsAbLDAPChangeLogQuery.h" +#include "nsIAbLDAPReplicationData.h" + /*** implementation of the service ******/ -NS_IMPL_THREADSAFE_ISUPPORTS1(nsAbLDAPReplicationService, nsIAbLDAPReplicationService) +NS_IMPL_ISUPPORTS1(nsAbLDAPReplicationService, nsIAbLDAPReplicationService) nsAbLDAPReplicationService::nsAbLDAPReplicationService() : mReplicating(PR_FALSE) @@ -78,6 +81,14 @@ NS_IMETHODIMP nsAbLDAPReplicationService::StartReplication(const nsACString & aP { case nsIAbLDAPProcessReplicationData::kDefaultDownloadAll : mQuery = do_CreateInstance(NS_ABLDAP_REPLICATIONQUERY_CONTRACTID, &rv); + break ; + case nsIAbLDAPProcessReplicationData::kChangeLogProtocol : + mQuery = do_CreateInstance (NS_ABLDAP_CHANGELOGQUERY_CONTRACTID, &rv); + break ; + default : + break; + } + if(NS_SUCCEEDED(rv) && mQuery) { rv = mQuery->Init(aPrefName, progressListener); @@ -91,13 +102,7 @@ NS_IMETHODIMP nsAbLDAPReplicationService::StartReplication(const nsACString & aP } } } - break; - default : - break; - } - // this should come here only in case of an error, either when DoReplicationQuery errors out - // of if DecideProtocol returns an error. if(progressListener && NS_FAILED(rv)) progressListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_STOP, PR_FALSE); @@ -139,8 +144,9 @@ NS_IMETHODIMP nsAbLDAPReplicationService::Done(PRBool aSuccess) // if it exists ChangeLog protocol is supported. PRInt32 nsAbLDAPReplicationService::DecideProtocol() { - // currently only Replicate All is implemented - return nsIAbLDAPProcessReplicationData::kDefaultDownloadAll; + // do the changeLog, it will decide if there is a need to replicate all + // entries or only update existing DB and will do the approprite thing. + return nsIAbLDAPProcessReplicationData::kChangeLogProtocol; } diff --git a/mailnews/addrbook/src/nsAddrDatabase.cpp b/mailnews/addrbook/src/nsAddrDatabase.cpp index 173b7839f3f..96950fab49a 100644 --- a/mailnews/addrbook/src/nsAddrDatabase.cpp +++ b/mailnews/addrbook/src/nsAddrDatabase.cpp @@ -2936,11 +2936,8 @@ nsresult nsAddrDatabase::CreateCard(nsIMdbRow* cardRow, mdb_id listRowID, nsIAbC if(NS_SUCCEEDED(rv)) { nsCOMPtr personCard; - nsCOMPtr dbm_dbDirectory(do_QueryInterface(m_dbDirectory,&rv)); - if (NS_SUCCEEDED(rv) && dbm_dbDirectory) { personCard = do_CreateInstance(NS_ABMDBCARD_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); - } nsCOMPtr dbpersonCard (do_QueryInterface(personCard, &rv));