Back to index

lightning-sunbird  0.9+nobinonly
nsIMAPHostSessionList.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.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 "msgCore.h"
00040 #include "nsIMAPHostSessionList.h"
00041 #include "nsIMAPBodyShell.h"
00042 #include "nsIMAPNamespace.h"
00043 #include "nsISupportsUtils.h"
00044 #include "nsIImapIncomingServer.h"
00045 #include "nsCOMPtr.h"
00046 #include "nsIMsgIncomingServer.h"
00047 #include "nsIObserverService.h"
00048 
00049 nsIMAPHostInfo::nsIMAPHostInfo(const char *serverKey, 
00050                                nsIImapIncomingServer *server)
00051 {
00052   fServerKey = nsCRT::strdup(serverKey);
00053   NS_ASSERTION(server, "*** Fatal null imap incoming server...\n");
00054   fOnlineDir = NULL;
00055   server->GetServerDirectory(&fOnlineDir);
00056   fNextHost = NULL;
00057   fCachedPassword = NULL;
00058   fCapabilityFlags = kCapabilityUndefined;
00059   fHierarchyDelimiters = NULL;
00060 #ifdef DEBUG_bienvenu1
00061   fHaveWeEverDiscoveredFolders = PR_TRUE; // try this, see what bad happens - we'll need to 
00062   // figure out a way to make new accounts have it be false
00063 #else
00064   fHaveWeEverDiscoveredFolders = PR_FALSE; // try this, see what bad happens
00065 #endif
00066   fCanonicalOnlineSubDir = NULL;
00067   fNamespaceList = nsIMAPNamespaceList::CreatensIMAPNamespaceList();
00068   fUsingSubscription = PR_TRUE;
00069   server->GetUsingSubscription(&fUsingSubscription);
00070   fOnlineTrashFolderExists = PR_FALSE;
00071   fShouldAlwaysListInbox = PR_TRUE;
00072   fShellCache = nsIMAPBodyShellCache::Create();
00073   fPasswordVerifiedOnline = PR_FALSE;
00074   fDeleteIsMoveToTrash = PR_TRUE;
00075   fShowDeletedMessages = PR_FALSE;
00076   fGotNamespaces = PR_FALSE;
00077   fHaveAdminURL = PR_FALSE;
00078   fNamespacesOverridable = PR_TRUE;
00079   server->GetOverrideNamespaces(&fNamespacesOverridable);
00080   fTempNamespaceList = nsIMAPNamespaceList::CreatensIMAPNamespaceList();
00081 }
00082 
00083 nsIMAPHostInfo::~nsIMAPHostInfo()
00084 {
00085   PR_Free(fServerKey);
00086   PR_Free(fCachedPassword);
00087   PR_Free(fHierarchyDelimiters);
00088   PR_Free(fOnlineDir);
00089   delete fNamespaceList;
00090   delete fTempNamespaceList;
00091   delete fShellCache;
00092 }
00093 
00094 NS_IMPL_THREADSAFE_ISUPPORTS3(nsIMAPHostSessionList,
00095                               nsIImapHostSessionList,
00096                               nsIObserver,
00097                               nsISupportsWeakReference)
00098 
00099                               
00100 nsIMAPHostSessionList::nsIMAPHostSessionList()
00101 {
00102   gCachedHostInfoMonitor = PR_NewMonitor(/* "accessing-hostlist-monitor"*/);
00103   fHostInfoList = nsnull;
00104 }
00105 
00106 nsIMAPHostSessionList::~nsIMAPHostSessionList()
00107 {
00108   ResetAll();
00109   PR_DestroyMonitor(gCachedHostInfoMonitor);
00110 }
00111 
00112 nsresult nsIMAPHostSessionList::Init()
00113 {
00114   nsresult rv;
00115   nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
00116   if (NS_SUCCEEDED(rv))
00117   {
00118     observerService->AddObserver(this, "profile-before-change", PR_TRUE);
00119     observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
00120   }
00121   return rv;
00122 }
00123 
00124 
00125 NS_IMETHODIMP nsIMAPHostSessionList::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
00126 {
00127   nsresult rv;  
00128   if (!strcmp(aTopic, "profile-before-change")) 
00129     ResetAll();
00130   else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
00131   {
00132     nsCOMPtr<nsIObserverService> observerService =  do_GetService("@mozilla.org/observer-service;1", &rv);
00133     if (NS_SUCCEEDED(rv))
00134     {    
00135       observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
00136       observerService->RemoveObserver(this, "profile-before-change");
00137     }
00138   }
00139   return NS_OK;
00140 }
00141 
00142 nsIMAPHostInfo *nsIMAPHostSessionList::FindHost(const char *serverKey)
00143 {
00144   nsIMAPHostInfo *host;
00145   
00146   // ### should also check userName here, if NON NULL
00147   for (host = fHostInfoList; host; host = host->fNextHost)
00148   {
00149     if (!PL_strcasecmp(serverKey, host->fServerKey)) 
00150       return host;
00151   }
00152   return host;
00153 }
00154 
00155 // reset any cached connection info - delete the lot of 'em
00156 NS_IMETHODIMP nsIMAPHostSessionList::ResetAll()
00157 {
00158   PR_EnterMonitor(gCachedHostInfoMonitor);
00159   nsIMAPHostInfo *nextHost = NULL;
00160   for (nsIMAPHostInfo *host = fHostInfoList; host; host = nextHost)
00161   {
00162     nextHost = host->fNextHost;
00163     delete host;
00164   }
00165   fHostInfoList = NULL;
00166   PR_ExitMonitor(gCachedHostInfoMonitor);
00167   return NS_OK;
00168 }
00169 
00170 NS_IMETHODIMP
00171 nsIMAPHostSessionList::AddHostToList(const char *serverKey,
00172                                      nsIImapIncomingServer *server)
00173 {
00174   nsIMAPHostInfo *newHost=NULL;
00175   PR_EnterMonitor(gCachedHostInfoMonitor);
00176   if (!FindHost(serverKey))
00177   {
00178     // stick it on the front
00179     newHost = new nsIMAPHostInfo(serverKey, server);
00180     if (newHost)
00181     {
00182       newHost->fNextHost = fHostInfoList;
00183       fHostInfoList = newHost;
00184     }
00185   }
00186   PR_ExitMonitor(gCachedHostInfoMonitor);
00187   return (newHost == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00188 }
00189 
00190 NS_IMETHODIMP nsIMAPHostSessionList::GetCapabilityForHost(const char *serverKey, PRUint32 &result)
00191 {
00192   PR_EnterMonitor(gCachedHostInfoMonitor);
00193   
00194   nsIMAPHostInfo *host = FindHost(serverKey);
00195   result = (host) ? host->fCapabilityFlags : 0;
00196   PR_ExitMonitor(gCachedHostInfoMonitor);
00197   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00198 }
00199 
00200 NS_IMETHODIMP nsIMAPHostSessionList::SetCapabilityForHost(const char *serverKey, PRUint32 capability)
00201 {
00202   PR_EnterMonitor(gCachedHostInfoMonitor);
00203   nsIMAPHostInfo *host = FindHost(serverKey);
00204   if (host)
00205     host->fCapabilityFlags = capability;
00206   PR_ExitMonitor(gCachedHostInfoMonitor);
00207   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00208 }
00209 
00210 NS_IMETHODIMP nsIMAPHostSessionList::GetPasswordForHost(const char *serverKey, nsString &result)
00211 {
00212   PR_EnterMonitor(gCachedHostInfoMonitor);
00213   nsIMAPHostInfo *host = FindHost(serverKey);
00214   if (host)
00215     result.AssignWithConversion(host->fCachedPassword);
00216   PR_ExitMonitor(gCachedHostInfoMonitor);
00217   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00218 }
00219 
00220 NS_IMETHODIMP nsIMAPHostSessionList::SetPasswordForHost(const char *serverKey, const char *password)
00221 {
00222   PR_EnterMonitor(gCachedHostInfoMonitor);
00223   nsIMAPHostInfo *host = FindHost(serverKey);
00224   if (host)
00225   {
00226     PR_FREEIF(host->fCachedPassword);
00227     if (password)
00228       host->fCachedPassword = nsCRT::strdup(password);
00229   }
00230   PR_ExitMonitor(gCachedHostInfoMonitor);
00231   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00232 }
00233 
00234 NS_IMETHODIMP nsIMAPHostSessionList::SetPasswordVerifiedOnline(const char *serverKey)
00235 {
00236   PR_EnterMonitor(gCachedHostInfoMonitor);
00237   nsIMAPHostInfo *host = FindHost(serverKey);
00238   if (host)
00239     host->fPasswordVerifiedOnline = PR_TRUE;
00240   PR_ExitMonitor(gCachedHostInfoMonitor);
00241   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00242 }
00243 
00244 NS_IMETHODIMP nsIMAPHostSessionList::GetPasswordVerifiedOnline(const char *serverKey, PRBool &result)
00245 {
00246   
00247   PR_EnterMonitor(gCachedHostInfoMonitor);
00248   nsIMAPHostInfo *host = FindHost(serverKey);
00249   if (host)
00250     result = host->fPasswordVerifiedOnline;
00251   PR_ExitMonitor(gCachedHostInfoMonitor);
00252   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00253 }
00254 
00255 NS_IMETHODIMP nsIMAPHostSessionList::GetOnlineDirForHost(const char *serverKey,
00256                                                          nsString &result)
00257 {
00258   PR_EnterMonitor(gCachedHostInfoMonitor);
00259   nsIMAPHostInfo *host = FindHost(serverKey);
00260   if (host)
00261     result.AssignWithConversion(host->fOnlineDir);
00262   PR_ExitMonitor(gCachedHostInfoMonitor);
00263   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00264 }
00265 
00266 NS_IMETHODIMP nsIMAPHostSessionList::SetOnlineDirForHost(const char *serverKey,
00267                                                          const char *onlineDir)
00268 {
00269   PR_EnterMonitor(gCachedHostInfoMonitor);
00270   nsIMAPHostInfo *host = FindHost(serverKey);
00271   if (host)
00272   {
00273     PR_FREEIF(host->fOnlineDir);
00274     if (onlineDir)
00275       host->fOnlineDir = nsCRT::strdup(onlineDir);
00276   }
00277   PR_ExitMonitor(gCachedHostInfoMonitor);
00278   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00279 }
00280 
00281 NS_IMETHODIMP nsIMAPHostSessionList::GetDeleteIsMoveToTrashForHost(
00282                                                                    const char *serverKey, PRBool &result)
00283 {
00284   PR_EnterMonitor(gCachedHostInfoMonitor);
00285   nsIMAPHostInfo *host = FindHost(serverKey);
00286   if (host)
00287     result = host->fDeleteIsMoveToTrash;
00288   PR_ExitMonitor(gCachedHostInfoMonitor);
00289   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00290 }
00291 
00292 NS_IMETHODIMP nsIMAPHostSessionList::GetShowDeletedMessagesForHost(
00293                                                                    const char *serverKey, PRBool &result)
00294 {
00295   PR_EnterMonitor(gCachedHostInfoMonitor);
00296   nsIMAPHostInfo *host = FindHost(serverKey);
00297   if (host)
00298     result = host->fShowDeletedMessages;
00299   PR_ExitMonitor(gCachedHostInfoMonitor);
00300   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00301 }
00302 
00303 NS_IMETHODIMP nsIMAPHostSessionList::SetDeleteIsMoveToTrashForHost(
00304                                                                    const char *serverKey, PRBool isMoveToTrash)
00305 {
00306   PR_EnterMonitor(gCachedHostInfoMonitor);
00307   nsIMAPHostInfo *host = FindHost(serverKey);
00308   if (host)
00309     host->fDeleteIsMoveToTrash = isMoveToTrash;
00310   PR_ExitMonitor(gCachedHostInfoMonitor);
00311   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00312 }
00313 
00314 NS_IMETHODIMP nsIMAPHostSessionList::SetShowDeletedMessagesForHost(
00315                                                                    const char *serverKey, PRBool showDeletedMessages)
00316 {
00317   PR_EnterMonitor(gCachedHostInfoMonitor);
00318   nsIMAPHostInfo *host = FindHost(serverKey);
00319   if (host)
00320     host->fShowDeletedMessages = showDeletedMessages;
00321   PR_ExitMonitor(gCachedHostInfoMonitor);
00322   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00323 }
00324 
00325 NS_IMETHODIMP nsIMAPHostSessionList::GetGotNamespacesForHost(
00326                                                              const char *serverKey, PRBool &result)
00327 {
00328   PR_EnterMonitor(gCachedHostInfoMonitor);
00329   nsIMAPHostInfo *host = FindHost(serverKey);
00330   if (host)
00331     result = host->fGotNamespaces;
00332   PR_ExitMonitor(gCachedHostInfoMonitor);
00333   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00334 }
00335 
00336 NS_IMETHODIMP nsIMAPHostSessionList::SetGotNamespacesForHost(
00337                                                              const char *serverKey, PRBool gotNamespaces)
00338 {
00339   PR_EnterMonitor(gCachedHostInfoMonitor);
00340   nsIMAPHostInfo *host = FindHost(serverKey);
00341   if (host)
00342     host->fGotNamespaces = gotNamespaces;
00343   PR_ExitMonitor(gCachedHostInfoMonitor);
00344   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00345 }
00346 
00347 
00348 NS_IMETHODIMP nsIMAPHostSessionList::GetHostIsUsingSubscription(const char *serverKey, PRBool &result)
00349 {
00350   PR_EnterMonitor(gCachedHostInfoMonitor);
00351   nsIMAPHostInfo *host = FindHost(serverKey);
00352   if (host)
00353     result = host->fUsingSubscription;
00354   PR_ExitMonitor(gCachedHostInfoMonitor);
00355   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00356 }
00357 
00358 NS_IMETHODIMP nsIMAPHostSessionList::SetHostIsUsingSubscription(const char *serverKey, PRBool usingSubscription)
00359 {
00360   PR_EnterMonitor(gCachedHostInfoMonitor);
00361   nsIMAPHostInfo *host = FindHost(serverKey);
00362   if (host)
00363     host->fUsingSubscription = usingSubscription;
00364   PR_ExitMonitor(gCachedHostInfoMonitor);
00365   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00366 }
00367 
00368 NS_IMETHODIMP nsIMAPHostSessionList::GetHostHasAdminURL(const char *serverKey, PRBool &result)
00369 {
00370   PR_EnterMonitor(gCachedHostInfoMonitor);
00371   nsIMAPHostInfo *host = FindHost(serverKey);
00372   if (host)
00373     result = host->fHaveAdminURL;
00374   PR_ExitMonitor(gCachedHostInfoMonitor);
00375   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00376 }
00377 
00378 NS_IMETHODIMP nsIMAPHostSessionList::SetHostHasAdminURL(const char *serverKey, PRBool haveAdminURL)
00379 {
00380   PR_EnterMonitor(gCachedHostInfoMonitor);
00381   nsIMAPHostInfo *host = FindHost(serverKey);
00382   if (host)
00383     host->fHaveAdminURL = haveAdminURL;
00384   PR_ExitMonitor(gCachedHostInfoMonitor);
00385   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00386 }
00387 
00388 
00389 NS_IMETHODIMP nsIMAPHostSessionList::GetHaveWeEverDiscoveredFoldersForHost(const char *serverKey, PRBool &result)
00390 {
00391   PR_EnterMonitor(gCachedHostInfoMonitor);
00392   nsIMAPHostInfo *host = FindHost(serverKey);
00393   if (host)
00394     result = host->fHaveWeEverDiscoveredFolders;
00395   PR_ExitMonitor(gCachedHostInfoMonitor);
00396   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00397 }
00398 
00399 NS_IMETHODIMP nsIMAPHostSessionList::SetHaveWeEverDiscoveredFoldersForHost(const char *serverKey, PRBool discovered)
00400 {
00401   PR_EnterMonitor(gCachedHostInfoMonitor);
00402   nsIMAPHostInfo *host = FindHost(serverKey);
00403   if (host)
00404     host->fHaveWeEverDiscoveredFolders = discovered;
00405   PR_ExitMonitor(gCachedHostInfoMonitor);
00406   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00407 }
00408 
00409 NS_IMETHODIMP nsIMAPHostSessionList::SetOnlineTrashFolderExistsForHost(const char *serverKey, PRBool exists)
00410 {
00411   PR_EnterMonitor(gCachedHostInfoMonitor);
00412   nsIMAPHostInfo *host = FindHost(serverKey);
00413   if (host)
00414     host->fOnlineTrashFolderExists = exists;
00415   PR_ExitMonitor(gCachedHostInfoMonitor);
00416   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00417 }
00418 
00419 NS_IMETHODIMP nsIMAPHostSessionList::GetOnlineTrashFolderExistsForHost(const char *serverKey, PRBool &result)
00420 {
00421   
00422   PR_EnterMonitor(gCachedHostInfoMonitor);
00423   nsIMAPHostInfo *host = FindHost(serverKey);
00424   if (host)
00425     result = host->fOnlineTrashFolderExists;
00426   PR_ExitMonitor(gCachedHostInfoMonitor);
00427   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00428 }
00429 
00430 NS_IMETHODIMP nsIMAPHostSessionList::AddNewNamespaceForHost(const char *serverKey, nsIMAPNamespace *ns)
00431 {
00432   PR_EnterMonitor(gCachedHostInfoMonitor);
00433   nsIMAPHostInfo *host = FindHost(serverKey);
00434   if (host)
00435   {
00436     host->fNamespaceList->AddNewNamespace(ns);
00437   }
00438   PR_ExitMonitor(gCachedHostInfoMonitor);
00439   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00440 }
00441 
00442 NS_IMETHODIMP nsIMAPHostSessionList::SetNamespaceFromPrefForHost(const char *serverKey, 
00443                                                                  const char *namespacePref, EIMAPNamespaceType nstype)
00444 {
00445   PR_EnterMonitor(gCachedHostInfoMonitor);
00446   nsIMAPHostInfo *host = FindHost(serverKey);
00447   if (host)
00448   {
00449     if (namespacePref)
00450     {
00451       int numNamespaces = host->fNamespaceList->UnserializeNamespaces(namespacePref, nsnull, 0);
00452       char **prefixes = (char**) PR_CALLOC(numNamespaces * sizeof(char*));
00453       if (prefixes)
00454       {
00455         int len = host->fNamespaceList->UnserializeNamespaces(namespacePref, prefixes, numNamespaces);
00456         for (int i = 0; i < len; i++)
00457         {
00458           char *thisns = prefixes[i];
00459           char delimiter = '/';    // a guess
00460           if (PL_strlen(thisns) >= 1)
00461             delimiter = thisns[PL_strlen(thisns)-1];
00462           nsIMAPNamespace *ns = new nsIMAPNamespace(nstype, thisns, delimiter, PR_TRUE);
00463           if (ns)
00464             host->fNamespaceList->AddNewNamespace(ns);
00465           PR_FREEIF(thisns);
00466         }
00467         PR_Free(prefixes);
00468       }
00469     }
00470   }
00471   PR_ExitMonitor(gCachedHostInfoMonitor);
00472   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00473 }
00474 
00475 NS_IMETHODIMP nsIMAPHostSessionList::GetNamespaceForMailboxForHost(const char *serverKey, const char *mailbox_name, nsIMAPNamespace * &result)
00476 {
00477   PR_EnterMonitor(gCachedHostInfoMonitor);
00478   nsIMAPHostInfo *host = FindHost(serverKey);
00479   if (host)
00480   {
00481     result = host->fNamespaceList->GetNamespaceForMailbox(mailbox_name);
00482   }
00483   PR_ExitMonitor(gCachedHostInfoMonitor);
00484   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00485 }
00486 
00487 
00488 NS_IMETHODIMP nsIMAPHostSessionList::ClearPrefsNamespacesForHost(const char *serverKey)
00489 {
00490   PR_EnterMonitor(gCachedHostInfoMonitor);
00491   nsIMAPHostInfo *host = FindHost(serverKey);
00492   if (host)
00493   {
00494     host->fNamespaceList->ClearNamespaces(PR_TRUE, PR_FALSE, PR_TRUE);
00495   }
00496   PR_ExitMonitor(gCachedHostInfoMonitor);
00497   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00498 }
00499 
00500 
00501 NS_IMETHODIMP nsIMAPHostSessionList::ClearServerAdvertisedNamespacesForHost(const char *serverKey)
00502 {
00503   PR_EnterMonitor(gCachedHostInfoMonitor);
00504   nsIMAPHostInfo *host = FindHost(serverKey);
00505   if (host)
00506   {
00507     host->fNamespaceList->ClearNamespaces(PR_FALSE, PR_TRUE, PR_TRUE);
00508   }
00509   PR_ExitMonitor(gCachedHostInfoMonitor);
00510   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00511 }
00512 
00513 NS_IMETHODIMP nsIMAPHostSessionList::GetDefaultNamespaceOfTypeForHost(const char *serverKey, EIMAPNamespaceType type, nsIMAPNamespace * &result)
00514 {
00515   PR_EnterMonitor(gCachedHostInfoMonitor);
00516   nsIMAPHostInfo *host = FindHost(serverKey);
00517   if (host)
00518   {
00519     result = host->fNamespaceList->GetDefaultNamespaceOfType(type);
00520   }
00521   PR_ExitMonitor(gCachedHostInfoMonitor);
00522   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00523 }
00524 
00525 NS_IMETHODIMP nsIMAPHostSessionList::GetNamespacesOverridableForHost(const char *serverKey, PRBool &result)
00526 {
00527   PR_EnterMonitor(gCachedHostInfoMonitor);
00528   nsIMAPHostInfo *host = FindHost(serverKey);
00529   if (host)
00530     result = host->fNamespacesOverridable;
00531   PR_ExitMonitor(gCachedHostInfoMonitor);
00532   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00533 }
00534 
00535 NS_IMETHODIMP nsIMAPHostSessionList::SetNamespacesOverridableForHost(const char *serverKey, PRBool overridable)
00536 {
00537   PR_EnterMonitor(gCachedHostInfoMonitor);
00538   nsIMAPHostInfo *host = FindHost(serverKey);
00539   if (host)
00540     host->fNamespacesOverridable = overridable;
00541   PR_ExitMonitor(gCachedHostInfoMonitor);
00542   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00543 }
00544 
00545 NS_IMETHODIMP nsIMAPHostSessionList::GetNumberOfNamespacesForHost(const char *serverKey, PRUint32 &result)
00546 {
00547   PRInt32 intResult = 0;
00548   
00549   PR_EnterMonitor(gCachedHostInfoMonitor);
00550   nsIMAPHostInfo *host = FindHost(serverKey);
00551   if (host)
00552   {
00553     intResult = host->fNamespaceList->GetNumberOfNamespaces();
00554   }
00555   PR_ExitMonitor(gCachedHostInfoMonitor);
00556   NS_ASSERTION(intResult >= 0, "negative number of namespaces");
00557   result = (PRUint32) intResult;
00558   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00559 }
00560 
00561 NS_IMETHODIMP nsIMAPHostSessionList::GetNamespaceNumberForHost(const char *serverKey, PRInt32 n, nsIMAPNamespace * &result)
00562 {
00563   PR_EnterMonitor(gCachedHostInfoMonitor);
00564   nsIMAPHostInfo *host = FindHost(serverKey);
00565   if (host)
00566   {
00567     result = host->fNamespaceList->GetNamespaceNumber(n);
00568   }
00569   PR_ExitMonitor(gCachedHostInfoMonitor);
00570   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00571 }
00572 
00573 nsresult nsIMAPHostSessionList::SetNamespacesPrefForHost(nsIImapIncomingServer *aHost, EIMAPNamespaceType type, char *pref)
00574 {
00575   if (type == kPersonalNamespace)
00576     aHost->SetPersonalNamespace(pref);
00577   else if (type == kPublicNamespace)
00578     aHost->SetPublicNamespace(pref);
00579   else if (type == kOtherUsersNamespace)
00580     aHost->SetOtherUsersNamespace(pref);
00581   else
00582     NS_ASSERTION(PR_FALSE, "bogus namespace type");
00583   return NS_OK;
00584   
00585 }
00586 // do we need this? What should we do about the master thing?
00587 // Make sure this is running in the Mozilla thread when called
00588 NS_IMETHODIMP nsIMAPHostSessionList::CommitNamespacesForHost(nsIImapIncomingServer *aHost)
00589 {
00590   char * serverKey = nsnull;
00591   
00592   if (!aHost)
00593     return NS_ERROR_NULL_POINTER;
00594   
00595   nsCOMPtr <nsIMsgIncomingServer> incomingServer = do_QueryInterface(aHost);
00596   if (!incomingServer)
00597     return NS_ERROR_NULL_POINTER;
00598   
00599   nsresult rv = incomingServer->GetKey(&serverKey);
00600   if (NS_FAILED(rv)) return rv;
00601   
00602   PR_EnterMonitor(gCachedHostInfoMonitor);
00603   nsIMAPHostInfo *host = FindHost(serverKey);
00604   if (host)
00605   {
00606     host->fGotNamespaces = PR_TRUE;       // so we only issue NAMESPACE once per host per session.
00607     EIMAPNamespaceType type = kPersonalNamespace;
00608     for (int i = 1; i <= 3; i++)
00609     {
00610       switch(i)
00611       {
00612       case 1:
00613         type = kPersonalNamespace;
00614         break;
00615       case 2:
00616         type = kPublicNamespace;
00617         break;
00618       case 3:
00619         type = kOtherUsersNamespace;
00620         break;
00621       default:
00622         type = kPersonalNamespace;
00623         break;
00624       }
00625       
00626       int32 numInNS = host->fNamespaceList->GetNumberOfNamespaces(type);
00627       if (numInNS == 0)
00628       {
00629         SetNamespacesPrefForHost(aHost, type, NULL);
00630       }
00631       else if (numInNS >= 1)
00632       {
00633         char *pref = PR_smprintf("");
00634         for (int count = 1; count <= numInNS; count++)
00635         {
00636           nsIMAPNamespace *ns = host->fNamespaceList->GetNamespaceNumber(count, type);
00637           if (ns)
00638           {
00639             if (count > 1)
00640             {
00641               // append the comma
00642               char *tempPref = PR_smprintf("%s,",pref);
00643               PR_FREEIF(pref);
00644               pref = tempPref;
00645             }
00646             char *tempPref = PR_smprintf("%s\"%s\"",pref,ns->GetPrefix());
00647             PR_FREEIF(pref);
00648             pref = tempPref;
00649           }
00650         }
00651         if (pref)
00652         {
00653           SetNamespacesPrefForHost(aHost, type, pref);
00654           PR_Free(pref);
00655         }
00656       }
00657     }
00658     // clear, but don't delete the entries in, the temp namespace list
00659     host->fTempNamespaceList->ClearNamespaces(PR_TRUE, PR_TRUE, PR_FALSE);
00660     
00661     // Now reset all of libmsg's namespace references.
00662     // Did I mention this needs to be running in the mozilla thread?
00663     aHost->ResetNamespaceReferences();
00664   }
00665   PR_FREEIF(serverKey);
00666   PR_ExitMonitor(gCachedHostInfoMonitor);
00667   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00668 }
00669 
00670 NS_IMETHODIMP nsIMAPHostSessionList::FlushUncommittedNamespacesForHost(const char *serverKey, PRBool &result)
00671 {
00672        PR_EnterMonitor(gCachedHostInfoMonitor);
00673        nsIMAPHostInfo *host = FindHost(serverKey);
00674        if (host)
00675        {
00676               host->fTempNamespaceList->ClearNamespaces(PR_TRUE, PR_TRUE, PR_TRUE);
00677        }
00678        PR_ExitMonitor(gCachedHostInfoMonitor);
00679        return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00680 }
00681 
00682 
00683 // Returns NULL if there is no personal namespace on the given host
00684 NS_IMETHODIMP nsIMAPHostSessionList::GetOnlineInboxPathForHost(const char *serverKey, nsString &result)
00685 {
00686   PR_EnterMonitor(gCachedHostInfoMonitor);
00687   nsIMAPHostInfo *host = FindHost(serverKey);
00688   if (host)
00689   {
00690     nsIMAPNamespace *ns = NULL;
00691     ns = host->fNamespaceList->GetDefaultNamespaceOfType(kPersonalNamespace);
00692     if (ns)
00693     {
00694       result.AssignWithConversion(ns->GetPrefix());
00695       result.AppendLiteral("INBOX");
00696     }
00697   }
00698   else
00699   {
00700     result.SetLength(0);
00701   }
00702   PR_ExitMonitor(gCachedHostInfoMonitor);
00703   return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00704 }
00705 
00706 NS_IMETHODIMP nsIMAPHostSessionList::GetShouldAlwaysListInboxForHost(const char* /*serverKey*/, PRBool &result)
00707 {
00708        result = PR_TRUE;
00709 
00710        /*
00711        PR_EnterMonitor(gCachedHostInfoMonitor);
00712        nsIMAPHostInfo *host = FindHost(serverKey);
00713        if (host)
00714               ret = host->fShouldAlwaysListInbox;
00715        PR_ExitMonitor(gCachedHostInfoMonitor);
00716        */
00717        return NS_OK;
00718 }
00719 
00720 NS_IMETHODIMP nsIMAPHostSessionList::SetShouldAlwaysListInboxForHost(const char *serverKey, PRBool shouldList)
00721 {
00722        PR_EnterMonitor(gCachedHostInfoMonitor);
00723        nsIMAPHostInfo *host = FindHost(serverKey);
00724        if (host)
00725               host->fShouldAlwaysListInbox = shouldList;
00726        PR_ExitMonitor(gCachedHostInfoMonitor);
00727        return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00728 }
00729 
00730 NS_IMETHODIMP nsIMAPHostSessionList::SetNamespaceHierarchyDelimiterFromMailboxForHost(const char *serverKey, const char *boxName, char delimiter)
00731 {
00732   PR_EnterMonitor(gCachedHostInfoMonitor);
00733   nsIMAPHostInfo *host = FindHost(serverKey);
00734   if (host)
00735   {
00736     nsIMAPNamespace *ns = host->fNamespaceList->GetNamespaceForMailbox(boxName);
00737     if (ns && !ns->GetIsDelimiterFilledIn())
00738     {
00739       ns->SetDelimiter(delimiter, PR_TRUE);
00740     }
00741   }
00742   PR_ExitMonitor(gCachedHostInfoMonitor);
00743   return (host) ? NS_OK : NS_ERROR_ILLEGAL_VALUE ;
00744 }
00745 
00746 NS_IMETHODIMP nsIMAPHostSessionList::AddShellToCacheForHost(const char *serverKey, nsIMAPBodyShell *shell)
00747 {
00748        PR_EnterMonitor(gCachedHostInfoMonitor);
00749        nsIMAPHostInfo *host = FindHost(serverKey);
00750        if (host)
00751        {
00752               if (host->fShellCache)
00753               {
00754                      PRBool rv = host->fShellCache->AddShellToCache(shell);
00755                      PR_ExitMonitor(gCachedHostInfoMonitor);
00756                      return rv;
00757               }
00758               else
00759               {
00760                      PR_ExitMonitor(gCachedHostInfoMonitor);
00761                      return PR_FALSE;
00762               }
00763        }
00764        PR_ExitMonitor(gCachedHostInfoMonitor);
00765        return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00766 }
00767 
00768 NS_IMETHODIMP nsIMAPHostSessionList::FindShellInCacheForHost(const char *serverKey, const char *mailboxName, const char *UID, 
00769                                                              IMAP_ContentModifiedType modType, nsIMAPBodyShell  **shell)
00770 {
00771        nsCString uidString(UID);
00772 
00773        PR_EnterMonitor(gCachedHostInfoMonitor);
00774        nsIMAPHostInfo *host = FindHost(serverKey);
00775        if (host)
00776        {
00777               if (host->fShellCache)
00778                      *shell = host->fShellCache->FindShellForUID(uidString, mailboxName, modType);
00779        }
00780        PR_ExitMonitor(gCachedHostInfoMonitor);
00781        return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;
00782 }