Back to index

lightning-sunbird  0.9+nobinonly
nsAbLDAPChangeLogData.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2002
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Rajiv Dayal <rdayal@netscape.com>
00023  *   Dan Mosedale <dan.mosedale@oracle.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsAbLDAPChangeLogData.h"
00040 #include "nsAbLDAPChangeLogQuery.h"
00041 #include "nsLDAP.h"
00042 #include "nsILDAPMessage.h"
00043 #include "nsIAbCard.h"
00044 #include "nsIAddrBookSession.h"
00045 #include "nsAbBaseCID.h"
00046 #include "nsAbUtils.h"
00047 #include "nsAbMDBCard.h"
00048 #include "nsAbLDAPCard.h"
00049 #include "nsProxiedService.h"
00050 #include "nsAutoLock.h"
00051 #include "nsIAuthPrompt.h"
00052 #include "nsIStringBundle.h"
00053 #include "nsIWindowWatcher.h"
00054 #include "nsUnicharUtils.h"
00055 
00056 // defined here since to be used 
00057 // only locally to this file.
00058 enum UpdateOp {
00059  NO_OP,
00060  ENTRY_ADD,
00061  ENTRY_DELETE,
00062  ENTRY_MODIFY
00063 };
00064 
00065 nsAbLDAPProcessChangeLogData::nsAbLDAPProcessChangeLogData()
00066 : mUseChangeLog(PR_FALSE),
00067   mChangeLogEntriesCount(0),
00068   mEntriesAddedQueryCount(0)
00069 {
00070    mRootDSEEntry.firstChangeNumber = 0;
00071    mRootDSEEntry.lastChangeNumber = 0;
00072 }
00073 
00074 nsAbLDAPProcessChangeLogData::~nsAbLDAPProcessChangeLogData()
00075 {
00076 
00077 }
00078 
00079 NS_IMETHODIMP nsAbLDAPProcessChangeLogData::Init(nsIAbLDAPReplicationQuery * query, nsIWebProgressListener *progressListener)
00080 {
00081    NS_ENSURE_ARG_POINTER(query);
00082 
00083    // here we are assuming that the caller will pass a nsAbLDAPChangeLogQuery object,
00084    // an implementation derived from the implementation of nsIAbLDAPReplicationQuery.
00085    nsresult rv = NS_OK;
00086    mChangeLogQuery = do_QueryInterface(query, &rv);
00087    if(NS_FAILED(rv))
00088        return rv;
00089    
00090    // call the parent's Init now
00091    return nsAbLDAPProcessReplicationData::Init(query, progressListener);
00092 }
00093 
00094 nsresult nsAbLDAPProcessChangeLogData::OnLDAPBind(nsILDAPMessage *aMessage)
00095 {
00096     NS_ENSURE_ARG_POINTER(aMessage);
00097        if(!mInitialized) 
00098         return NS_ERROR_NOT_INITIALIZED;
00099 
00100     PRInt32 errCode;
00101 
00102     nsresult rv = aMessage->GetErrorCode(&errCode);
00103     if(NS_FAILED(rv)) {
00104         Done(PR_FALSE);
00105         return rv;
00106     }
00107 
00108     if(errCode != nsILDAPErrors::SUCCESS) {
00109         Done(PR_FALSE);
00110         return NS_ERROR_FAILURE;
00111     }
00112 
00113     switch(mState) {
00114     case kAnonymousBinding :
00115         rv = GetAuthData();
00116         if(NS_SUCCEEDED(rv)) 
00117             rv = mChangeLogQuery->QueryAuthDN(mAuthUserID);
00118         if(NS_SUCCEEDED(rv)) 
00119             mState = kSearchingAuthDN;
00120         break;
00121     case kAuthenticatedBinding :
00122         rv = mChangeLogQuery->QueryRootDSE();
00123         if(NS_SUCCEEDED(rv)) 
00124             mState = kSearchingRootDSE;
00125         break;
00126     } //end of switch
00127 
00128     if(NS_FAILED(rv))
00129         Abort();
00130 
00131     return rv;
00132 }
00133 
00134 nsresult nsAbLDAPProcessChangeLogData::OnLDAPSearchEntry(nsILDAPMessage *aMessage)
00135 {
00136     NS_ENSURE_ARG_POINTER(aMessage);
00137     if(!mInitialized) 
00138         return NS_ERROR_NOT_INITIALIZED;
00139 
00140     nsresult rv = NS_OK;       
00141 
00142     switch(mState)
00143     {
00144     case kSearchingAuthDN :
00145         {
00146             nsCAutoString authDN;
00147             rv = aMessage->GetDn(authDN);
00148             if(NS_SUCCEEDED(rv) && !authDN.IsEmpty())
00149                 mAuthDN = authDN.get();
00150         }
00151         break;
00152     case kSearchingRootDSE:
00153         rv = ParseRootDSEEntry(aMessage);
00154         break;
00155     case kFindingChanges:
00156         rv = ParseChangeLogEntries(aMessage);
00157         break;
00158     // fall through since we only add (for updates we delete and add)
00159     case kReplicatingChanges:
00160     case kReplicatingAll :
00161         return nsAbLDAPProcessReplicationData::OnLDAPSearchEntry(aMessage);
00162     }
00163 
00164     if(NS_FAILED(rv))
00165         Abort();
00166 
00167     return rv;
00168 }
00169 
00170 nsresult nsAbLDAPProcessChangeLogData::OnLDAPSearchResult(nsILDAPMessage *aMessage)
00171 {
00172     NS_ENSURE_ARG_POINTER(aMessage);
00173     if(!mInitialized) 
00174         return NS_ERROR_NOT_INITIALIZED;
00175 
00176     PRInt32 errorCode;
00177     
00178     nsresult rv = aMessage->GetErrorCode(&errorCode);
00179 
00180     if(NS_SUCCEEDED(rv))
00181     {
00182         if(errorCode == nsILDAPErrors::SUCCESS || errorCode == nsILDAPErrors::SIZELIMIT_EXCEEDED) {
00183             switch(mState) {
00184             case kSearchingAuthDN :
00185                 rv = OnSearchAuthDNDone();
00186                 break;
00187             case kSearchingRootDSE:
00188              {
00189                 // before starting the changeLog check the DB file, if its not there or bogus
00190                 // we need to create a new one and set to all.
00191                 nsCOMPtr<nsIAddrBookSession> abSession = do_GetService(NS_ADDRBOOKSESSION_CONTRACTID, &rv);
00192                 if(NS_FAILED(rv)) 
00193                     break;
00194                 nsCOMPtr<nsILocalFile> dbPath;
00195                 rv = abSession->GetUserProfileDirectory(getter_AddRefs(dbPath));
00196                 if(NS_FAILED(rv)) 
00197                     break;
00198 
00199                 rv = dbPath->AppendNative(nsDependentCString(mDirServerInfo->replInfo->fileName));
00200                 if(NS_FAILED(rv)) 
00201                     break;
00202 
00203                 PRBool fileExists;
00204                 rv = dbPath->Exists(&fileExists);
00205                 if(NS_FAILED(rv)) 
00206                     break;
00207 
00208                 PRInt64 fileSize;
00209                 rv = dbPath->GetFileSize(&fileSize);
00210                 if(NS_FAILED(rv)) 
00211                     break;
00212 
00213                 if (!fileExists || !fileSize)
00214                     mUseChangeLog = PR_FALSE;
00215 
00216                 // open / create the AB here since it calls Done,
00217                 // just return from here. 
00218                 if (mUseChangeLog)
00219                    rv = OpenABForReplicatedDir(PR_FALSE);
00220                 else
00221                    rv = OpenABForReplicatedDir(PR_TRUE);
00222                 if (NS_FAILED(rv))
00223                    return rv;
00224                 
00225                 // now start the appropriate query
00226                 rv = OnSearchRootDSEDone();
00227                 break;
00228              }
00229             case kFindingChanges:
00230                 rv = OnFindingChangesDone();
00231                 // if success we return from here since
00232                 // this changes state to kReplicatingChanges
00233                 // and it falls thru into the if clause below.
00234                 if (NS_SUCCEEDED(rv))
00235                     return rv;
00236                 break;
00237             case kReplicatingAll :
00238                 return nsAbLDAPProcessReplicationData::OnLDAPSearchResult(aMessage);
00239             } // end of switch
00240         }
00241         else
00242             rv = NS_ERROR_FAILURE;
00243         // if one of the changed entry in changelog is not found, 
00244         // continue with replicating the next one.
00245         if(mState == kReplicatingChanges)
00246             rv = OnReplicatingChangeDone();
00247     } // end of outer if
00248 
00249     if(NS_FAILED(rv))
00250         Abort();
00251 
00252     return rv;
00253 }
00254 
00255 nsresult nsAbLDAPProcessChangeLogData::GetAuthData()
00256 {
00257     if(!mInitialized) 
00258         return NS_ERROR_NOT_INITIALIZED;
00259 
00260     nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
00261     if (!wwatch)
00262         return NS_ERROR_FAILURE;
00263     
00264     nsCOMPtr<nsIAuthPrompt> dialog;
00265     nsresult rv = wwatch->GetNewAuthPrompter(0, getter_AddRefs(dialog));
00266     if (NS_FAILED(rv))
00267         return rv;
00268     if (!dialog) 
00269         return NS_ERROR_FAILURE;
00270 
00271     nsCOMPtr<nsILDAPURL> url;
00272     rv = mQuery->GetReplicationURL(getter_AddRefs(url));
00273     if (NS_FAILED(rv))
00274         return rv;
00275 
00276     nsCAutoString serverUri;
00277     rv = url->GetSpec(serverUri);
00278     if (NS_FAILED(rv)) 
00279         return rv;
00280 
00281     nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
00282     if (NS_FAILED (rv)) 
00283         return rv ;
00284     nsCOMPtr<nsIStringBundle> bundle;
00285     rv = bundleService->CreateBundle("chrome://messenger/locale/addressbook/addressBook.properties", getter_AddRefs(bundle));
00286     if (NS_FAILED (rv)) 
00287         return rv ;
00288 
00289     nsXPIDLString title;
00290     rv = bundle->GetStringFromName(NS_LITERAL_STRING("AuthDlgTitle").get(), getter_Copies(title));
00291     if (NS_FAILED (rv)) 
00292         return rv ;
00293 
00294     nsXPIDLString desc;
00295     rv = bundle->GetStringFromName(NS_LITERAL_STRING("AuthDlgDesc").get(), getter_Copies(desc));
00296     if (NS_FAILED (rv)) 
00297         return rv ;
00298 
00299     nsXPIDLString username;
00300     nsXPIDLString password;
00301     PRBool btnResult = PR_FALSE;
00302        rv = dialog->PromptUsernameAndPassword(title, desc, 
00303                                             NS_ConvertUTF8toUCS2(serverUri).get(), 
00304                                             nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
00305                                             getter_Copies(username), getter_Copies(password), 
00306                                             &btnResult);
00307     if(NS_SUCCEEDED(rv) && btnResult) {
00308         CopyUTF16toUTF8(username, mAuthUserID);
00309         CopyUTF16toUTF8(password, mAuthPswd);
00310         mDirServerInfo->enableAuth=PR_TRUE;
00311         mDirServerInfo->savePassword=PR_TRUE;
00312     }
00313     else
00314         rv = NS_ERROR_FAILURE;
00315 
00316     return rv;
00317 }
00318 
00319 nsresult nsAbLDAPProcessChangeLogData::OnSearchAuthDNDone()
00320 {
00321     if(!mInitialized) 
00322         return NS_ERROR_NOT_INITIALIZED;
00323 
00324     nsCOMPtr<nsILDAPURL> url;
00325     nsresult rv = mQuery->GetReplicationURL(getter_AddRefs(url));
00326     if(NS_SUCCEEDED(rv))
00327         rv = mQuery->ConnectToLDAPServer(url, mAuthDN);
00328     if(NS_SUCCEEDED(rv)) {
00329         mState = kAuthenticatedBinding;
00330         PR_FREEIF(mDirServerInfo->authDn);
00331         mDirServerInfo->authDn=ToNewCString(mAuthDN);
00332     }
00333 
00334     return rv;
00335 }
00336 
00337 nsresult nsAbLDAPProcessChangeLogData::ParseRootDSEEntry(nsILDAPMessage *aMessage)
00338 {
00339     NS_ENSURE_ARG_POINTER(aMessage);
00340     if(!mInitialized) 
00341         return NS_ERROR_NOT_INITIALIZED;
00342 
00343     // populate the RootDSEChangeLogEntry
00344     CharPtrArrayGuard attrs;
00345     nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr());
00346     // no attributes !!!
00347     if(NS_FAILED(rv)) 
00348         return rv;
00349 
00350     for(PRInt32 i=attrs.GetSize()-1; i >= 0; i--) {
00351         PRUnicharPtrArrayGuard vals;
00352         rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr());
00353         if(NS_FAILED(rv))
00354             continue;
00355         if(vals.GetSize()) {
00356             if (!PL_strcasecmp(attrs[i], "changelog"))
00357                 CopyUTF16toUTF8(vals[0], mRootDSEEntry.changeLogDN);
00358             if (!PL_strcasecmp(attrs[i], "firstChangeNumber"))
00359                 mRootDSEEntry.firstChangeNumber = atol(NS_LossyConvertUCS2toASCII(vals[0]).get());
00360             if (!PL_strcasecmp(attrs[i], "lastChangeNumber"))
00361                 mRootDSEEntry.lastChangeNumber = atol(NS_LossyConvertUCS2toASCII(vals[0]).get());
00362             if (!PL_strcasecmp(attrs[i], "dataVersion"))
00363                 CopyUTF16toUTF8(vals[0], mRootDSEEntry.dataVersion);
00364         }
00365     }
00366 
00367     if((mRootDSEEntry.lastChangeNumber > 0) 
00368         && (mDirServerInfo->replInfo->lastChangeNumber < mRootDSEEntry.lastChangeNumber)
00369         && (mDirServerInfo->replInfo->lastChangeNumber > mRootDSEEntry.firstChangeNumber) 
00370       )
00371         mUseChangeLog = PR_TRUE;
00372 
00373     if(mRootDSEEntry.lastChangeNumber && (mDirServerInfo->replInfo->lastChangeNumber == mRootDSEEntry.lastChangeNumber)) {
00374         Done(PR_TRUE); // we are up to date no need to replicate, db not open yet so call Done
00375         return NS_OK;
00376     }
00377 
00378     return rv;
00379 }
00380 
00381 nsresult nsAbLDAPProcessChangeLogData::OnSearchRootDSEDone()
00382 {
00383     if(!mInitialized) 
00384         return NS_ERROR_NOT_INITIALIZED;
00385 
00386     nsresult rv = NS_OK;
00387 
00388     if(mUseChangeLog) {
00389         rv = mChangeLogQuery->QueryChangeLog(mRootDSEEntry.changeLogDN, mRootDSEEntry.lastChangeNumber);
00390         if (NS_FAILED(rv))
00391            return rv;
00392         mState = kFindingChanges;
00393         if(mListener)
00394             mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_FALSE);
00395     }
00396     else {
00397         rv = mQuery->QueryAllEntries();
00398         if (NS_FAILED(rv))
00399            return rv;
00400         mState = kReplicatingAll;
00401         if(mListener)
00402             mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_TRUE);
00403     }
00404 
00405     mDirServerInfo->replInfo->lastChangeNumber = mRootDSEEntry.lastChangeNumber;
00406     PR_FREEIF(mDirServerInfo->replInfo->dataVersion);
00407     mDirServerInfo->replInfo->dataVersion = ToNewCString(mRootDSEEntry.dataVersion);
00408 
00409     return rv;
00410 }
00411 
00412 nsresult nsAbLDAPProcessChangeLogData::ParseChangeLogEntries(nsILDAPMessage *aMessage)
00413 {
00414     NS_ENSURE_ARG_POINTER(aMessage);
00415     if(!mInitialized) 
00416         return NS_ERROR_NOT_INITIALIZED;
00417 
00418     // populate the RootDSEChangeLogEntry
00419     CharPtrArrayGuard attrs;
00420     nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr());
00421     // no attributes
00422     if(NS_FAILED(rv)) 
00423         return rv;
00424 
00425     nsAutoString targetDN;
00426     UpdateOp operation = NO_OP;
00427     for(PRInt32 i = attrs.GetSize()-1; i >= 0; i--) {
00428         PRUnicharPtrArrayGuard vals;
00429         rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr());
00430         if(NS_FAILED(rv))
00431             continue;
00432         if(vals.GetSize()) {
00433             if (!PL_strcasecmp(attrs[i], "targetdn"))
00434                 targetDN = vals[0];
00435             if (!PL_strcasecmp(attrs[i], "changetype")) {
00436                 if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("add"), nsCaseInsensitiveStringComparator()))
00437                     operation = ENTRY_ADD;
00438                 if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("modify"), nsCaseInsensitiveStringComparator()))
00439                     operation = ENTRY_MODIFY;
00440                 if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("delete"), nsCaseInsensitiveStringComparator()))
00441                     operation = ENTRY_DELETE;
00442             }
00443         }
00444     }
00445 
00446     mChangeLogEntriesCount++;
00447     if(!(mChangeLogEntriesCount % 10)) { // inform the listener every 10 entries
00448         mListener->OnProgressChange(nsnull,nsnull,mChangeLogEntriesCount, -1, mChangeLogEntriesCount, -1);
00449         // in case if the LDAP Connection thread is starved and causes problem
00450         // uncomment this one and try.
00451         // PR_Sleep(PR_INTERVAL_NO_WAIT); // give others a chance
00452     }
00453 
00454 #ifdef DEBUG_rdayal
00455     printf ("ChangeLog Replication : Updated Entry : %s for OpType : %u\n", 
00456                                     NS_ConvertUCS2toUTF8(targetDN).get(), operation);
00457 #endif
00458 
00459     switch(operation) {
00460     case ENTRY_ADD:
00461         // add the DN to the add list if not already in the list
00462         if(!(mEntriesToAdd.IndexOf(targetDN) >= 0))
00463             mEntriesToAdd.AppendString(targetDN);
00464         break;
00465     case ENTRY_DELETE:
00466         // donot check the return here since delete may fail if 
00467         // entry deleted in changelog doesnot exist in DB 
00468         // for e.g if the user specifies a filter, so go next entry
00469         DeleteCard(targetDN);
00470         break;
00471     case ENTRY_MODIFY:
00472         // for modify, delte the entry from DB and add updated entry
00473         // we do this since we cannot access the changes attribs of changelog
00474         rv = DeleteCard(targetDN);
00475         if (NS_SUCCEEDED(rv)) 
00476             if(!(mEntriesToAdd.IndexOf(targetDN) >= 0))
00477                 mEntriesToAdd.AppendString(targetDN);
00478         break;
00479     default:
00480         // should not come here, would come here only
00481         // if the entry is not a changeLog entry
00482         NS_WARNING("nsAbLDAPProcessChangeLogData::ParseChangeLogEntries"
00483            "Not an changelog entry");
00484     }
00485 
00486     // go ahead processing the next entry,  a modify or delete DB operation 
00487     // can 'correctly' fail if the entry is not present in the DB. 
00488     // eg : in case a filter is specified.
00489     return NS_OK;
00490 }
00491 
00492 nsresult nsAbLDAPProcessChangeLogData::OnFindingChangesDone()
00493 {
00494     if(!mInitialized) 
00495         return NS_ERROR_NOT_INITIALIZED;
00496 
00497 #ifdef DEBUG_rdayal
00498     printf ("ChangeLog Replication : Finding Changes Done \n");
00499 #endif
00500 
00501     nsresult rv = NS_OK;
00502 
00503     // no entries to add/update (for updates too we delete and add) entries,
00504     // we took care of deletes in ParseChangeLogEntries, all Done!
00505     mEntriesAddedQueryCount = mEntriesToAdd.Count();
00506     if(mEntriesAddedQueryCount <= 0) {
00507         if(mReplicationDB && mDBOpen) {
00508             // close the DB, no need to commit since we have not made
00509             // any changes yet to the DB.
00510             rv = mReplicationDB->Close(PR_FALSE);
00511             NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB Close(no commit) on Success failed");
00512             mDBOpen = PR_FALSE;
00513             // once are done with the replication file, delete the backup file
00514             if(mBackupReplicationFile) {
00515                 rv = mBackupReplicationFile->Remove(PR_FALSE);
00516                 NS_ASSERTION(NS_SUCCEEDED(rv), "Replication BackupFile Remove on Success failed");
00517             }
00518         }
00519         Done(PR_TRUE);
00520         return NS_OK;
00521     }
00522 
00523     // decrement the count first to get the correct array element
00524     mEntriesAddedQueryCount--;
00525     rv = mChangeLogQuery->QueryChangedEntries(NS_ConvertUCS2toUTF8(*(mEntriesToAdd[mEntriesAddedQueryCount])));
00526     if (NS_FAILED(rv))
00527         return rv;
00528 
00529     if(mListener && NS_SUCCEEDED(rv))
00530         mListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_START, PR_TRUE);
00531 
00532     mState = kReplicatingChanges;
00533     return rv;
00534 }
00535 
00536 nsresult nsAbLDAPProcessChangeLogData::OnReplicatingChangeDone()
00537 {
00538     if(!mInitialized) 
00539         return NS_ERROR_NOT_INITIALIZED;
00540 
00541     nsresult rv = NS_OK;
00542 
00543     if(!mEntriesAddedQueryCount)
00544     {
00545         if(mReplicationDB && mDBOpen) {
00546             rv = mReplicationDB->Close(PR_TRUE); // commit and close the DB
00547             NS_ASSERTION(NS_SUCCEEDED(rv), "Replication DB Close (commit) on Success failed");
00548             mDBOpen = PR_FALSE;
00549         }
00550         // once we done with the replication file, delete the backup file
00551         if(mBackupReplicationFile) {
00552             rv = mBackupReplicationFile->Remove(PR_FALSE);
00553             NS_ASSERTION(NS_SUCCEEDED(rv), "Replication BackupFile Remove on Success failed");
00554         }
00555         Done(PR_TRUE);  // all data is recieved
00556         return NS_OK;
00557     }
00558 
00559     // remove the entry already added from the list and query the next one
00560     if(mEntriesAddedQueryCount < mEntriesToAdd.Count() && mEntriesAddedQueryCount >= 0)
00561         mEntriesToAdd.RemoveStringAt(mEntriesAddedQueryCount);
00562     mEntriesAddedQueryCount--;
00563     rv = mChangeLogQuery->QueryChangedEntries(NS_ConvertUCS2toUTF8(*(mEntriesToAdd[mEntriesAddedQueryCount])));
00564 
00565     return rv;
00566 }
00567