Back to index

lightning-sunbird  0.9+nobinonly
nsPop3IncomingServer.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "prmem.h"
00039 #include "plstr.h"
00040 #include "prprf.h"
00041 
00042 #include "nsCOMPtr.h"
00043 
00044 #include "nsXPIDLString.h"
00045 #include "nsIStringBundle.h"
00046 
00047 #include "nsIPop3IncomingServer.h"
00048 #include "nsPop3IncomingServer.h"
00049 #include "nsIPop3Service.h"
00050 #include "nsMsgBaseCID.h"
00051 #include "nsMsgLocalCID.h"
00052 #include "nsMsgFolderFlags.h"
00053 #include "nsIFileSpec.h"
00054 #include "nsPop3Protocol.h"
00055 #include "nsIMsgLocalMailFolder.h"
00056 #include "nsIMsgAccountManager.h"
00057 #include "nsIMsgMailNewsUrl.h"
00058 #include "nsIRDFResource.h"
00059 #include "nsIRDFService.h"
00060 #include "nsRDFCID.h"
00061 
00062 static NS_DEFINE_CID(kCPop3ServiceCID, NS_POP3SERVICE_CID);
00063 
00064 class nsPop3GetMailChainer : public nsIUrlListener
00065 {
00066 public:
00067   NS_DECL_ISUPPORTS
00068   NS_DECL_NSIURLLISTENER
00069 
00070   nsPop3GetMailChainer();
00071   ~nsPop3GetMailChainer();
00072   nsresult GetNewMailForServers(nsISupportsArray *servers, nsIMsgWindow *msgWindow,
00073                                 nsIMsgFolder *folderToDownloadTo, nsIUrlListener *listener);
00074   nsresult RunNextGetNewMail();
00075 protected:
00076   nsCOMPtr <nsIMsgFolder> m_folderToDownloadTo;
00077   nsCOMPtr <nsIMsgWindow> m_downloadingMsgWindow;
00078   nsCOMPtr <nsISupportsArray> m_serversToGetNewMailFor;
00079   nsCOMPtr <nsIUrlListener> m_listener;
00080 };
00081 
00082 
00083 
00084 NS_IMPL_ISUPPORTS_INHERITED2(nsPop3IncomingServer,
00085                              nsMsgIncomingServer,
00086                              nsIPop3IncomingServer,
00087                           nsILocalMailIncomingServer)
00088 
00089 nsPop3IncomingServer::nsPop3IncomingServer()
00090 {    
00091     m_capabilityFlags = 
00092         POP3_AUTH_MECH_UNDEFINED |
00093         POP3_HAS_AUTH_USER |               // should be always there
00094         POP3_GURL_UNDEFINED |
00095         POP3_UIDL_UNDEFINED |
00096         POP3_TOP_UNDEFINED |
00097         POP3_XTND_XLST_UNDEFINED;
00098 
00099     m_canHaveFilters = PR_TRUE;
00100     m_authenticated = PR_FALSE;
00101 }
00102 
00103 nsPop3IncomingServer::~nsPop3IncomingServer()
00104 {
00105 }
00106 
00107 
00108 NS_IMPL_SERVERPREF_BOOL(nsPop3IncomingServer,
00109                         LeaveMessagesOnServer,
00110                         "leave_on_server")
00111 
00112 NS_IMPL_SERVERPREF_BOOL(nsPop3IncomingServer,
00113                         HeadersOnly,
00114                         "headers_only")
00115 
00116 NS_IMPL_SERVERPREF_BOOL(nsPop3IncomingServer,
00117                         DeleteMailLeftOnServer,
00118                         "delete_mail_left_on_server")
00119 
00120 NS_IMPL_SERVERPREF_BOOL(nsPop3IncomingServer,
00121                         AuthLogin,
00122                         "auth_login")
00123 
00124 NS_IMPL_SERVERPREF_BOOL(nsPop3IncomingServer,
00125                         DotFix,
00126                         "dot_fix")
00127 
00128 NS_IMPL_SERVERPREF_BOOL(nsPop3IncomingServer,
00129                         DeleteByAgeFromServer,
00130                         "delete_by_age_from_server")
00131 
00132 NS_IMPL_SERVERPREF_INT(nsPop3IncomingServer,
00133                         NumDaysToLeaveOnServer,
00134                         "num_days_to_leave_on_server")
00135 
00136 
00137 NS_IMPL_SERVERPREF_BOOL(nsPop3IncomingServer,
00138                             DeferGetNewMail,
00139                             "defer_get_new_mail")
00140 
00141 NS_IMETHODIMP nsPop3IncomingServer::GetDeferredToAccount(char **aRetVal)
00142 {
00143   return GetCharValue("deferred_to_account", aRetVal);
00144 }
00145 
00146 NS_IMETHODIMP nsPop3IncomingServer::SetDeferredToAccount(const char *aAccountKey)
00147 {
00148   nsXPIDLCString deferredToAccount;
00149   GetDeferredToAccount(getter_Copies(deferredToAccount));
00150   m_rootMsgFolder = nsnull; // clear this so we'll recalculate it on demand.
00151   //Notify listeners who listen to every folder
00152 
00153   nsresult rv =  SetCharValue("deferred_to_account", aAccountKey);
00154   NS_ENSURE_SUCCESS(rv, rv);
00155   nsCOMPtr<nsIFolderListener> folderListenerManager =
00156            do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
00157   if (NS_SUCCEEDED(rv))
00158   {
00159 
00160     nsCOMPtr<nsIMsgFolder> rootFolder;
00161     // use GetRootFolder, because that returns the real
00162     // root, not the deferred to root.
00163     rv = GetRootFolder(getter_AddRefs(rootFolder));
00164     if (rootFolder)
00165     {
00166       // if isDeferred state has changed, send notification
00167       if (((aAccountKey && *aAccountKey)  == deferredToAccount.IsEmpty())) 
00168       {
00169         
00170         nsCOMPtr <nsIRDFResource> folderRes = do_QueryInterface(rootFolder);
00171         nsCOMPtr <nsIAtom> deferAtom = getter_AddRefs(NS_NewAtom("isDeferred"));
00172         nsCOMPtr <nsIAtom> canFileAtom = getter_AddRefs(NS_NewAtom("CanFileMessages"));
00173         folderListenerManager->OnItemBoolPropertyChanged(folderRes, deferAtom, 
00174                   !deferredToAccount.IsEmpty(), deferredToAccount.IsEmpty());
00175         folderListenerManager->OnItemBoolPropertyChanged(folderRes, canFileAtom, 
00176                   deferredToAccount.IsEmpty(), !deferredToAccount.IsEmpty());
00177 
00178         // this hack causes the account manager ds to send notifications to the
00179         // xul content builder that make the changed acct appear or disappear
00180         // from the folder pane and related menus.
00181         nsCOMPtr<nsIMsgAccountManager> acctMgr = 
00182                             do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID);
00183         if (acctMgr)
00184         {
00185           acctMgr->NotifyServerUnloaded(this);
00186           acctMgr->NotifyServerLoaded(this);
00187           // check if this newly deferred to account is the local folders account
00188           // and needs to have a newly created INBOX.
00189           if (aAccountKey && *aAccountKey)
00190           {
00191             nsCOMPtr <nsIMsgAccount> account;
00192             acctMgr->GetAccount(aAccountKey, getter_AddRefs(account));
00193             if (account)
00194             {
00195               nsCOMPtr <nsIMsgIncomingServer> server;
00196               account->GetIncomingServer(getter_AddRefs(server));
00197               if (server)
00198               {
00199                 nsCOMPtr <nsILocalMailIncomingServer> incomingLocalServer = do_QueryInterface(server);
00200                 if (incomingLocalServer)
00201                 {
00202                   nsCOMPtr <nsIMsgFolder> rootFolder;
00203                   rv = server->GetRootFolder(getter_AddRefs(rootFolder));
00204                   NS_ENSURE_SUCCESS(rv, rv);
00205                   // this will fail if it already exists, which is fine.
00206                   rootFolder->CreateSubfolder(NS_LITERAL_STRING("Inbox").get(), nsnull);
00207                 }
00208               }
00209             }
00210           }
00211         }
00212       }
00213     }
00214   }
00215   return rv;  
00216 }
00217 
00218 //NS_IMPL_GETSET(nsPop3IncomingServer, Authenticated, PRBool, m_authenticated);
00219 
00220 NS_IMETHODIMP nsPop3IncomingServer::GetAuthenticated(PRBool *aAuthenticated)
00221 {
00222   NS_ENSURE_ARG_POINTER(aAuthenticated);
00223   *aAuthenticated = m_authenticated;
00224   return NS_OK;
00225 }
00226 
00227 NS_IMETHODIMP nsPop3IncomingServer::SetAuthenticated(PRBool aAuthenticated)
00228 {
00229   m_authenticated = aAuthenticated;
00230   return NS_OK;
00231 }
00232 
00233 nsresult 
00234 nsPop3IncomingServer::GetPop3CapabilityFlags(PRUint32 *flags)
00235 {
00236     *flags = m_capabilityFlags;
00237     return NS_OK;
00238 }
00239 
00240 nsresult
00241 nsPop3IncomingServer::SetPop3CapabilityFlags(PRUint32 flags)
00242 {
00243     m_capabilityFlags = flags;
00244     return NS_OK;
00245 }
00246 
00247 nsresult
00248 nsPop3IncomingServer::GetLocalStoreType(char **type)
00249 {
00250     NS_ENSURE_ARG_POINTER(type);
00251     *type = strdup("mailbox");
00252     return NS_OK;
00253 }
00254 
00255 
00256 NS_IMETHODIMP
00257 nsPop3IncomingServer::GetRootMsgFolder(nsIMsgFolder **aRootMsgFolder)
00258 {
00259   NS_ENSURE_ARG_POINTER(aRootMsgFolder);
00260   nsresult rv = NS_OK;
00261   if (!m_rootMsgFolder)
00262   {
00263     nsXPIDLCString deferredToAccount;
00264     GetDeferredToAccount(getter_Copies(deferredToAccount));
00265     if (deferredToAccount.IsEmpty())
00266     {
00267       rv = CreateRootFolder();
00268       m_rootMsgFolder = m_rootFolder;
00269     }
00270     else
00271     {
00272       nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
00273       NS_ENSURE_SUCCESS(rv,rv);
00274       nsCOMPtr <nsIMsgAccount> account;
00275       rv = accountManager->GetAccount(deferredToAccount, getter_AddRefs(account));
00276       NS_ENSURE_SUCCESS(rv,rv);
00277       if (account)
00278       {
00279         nsCOMPtr <nsIMsgIncomingServer> incomingServer;
00280         rv = account->GetIncomingServer(getter_AddRefs(incomingServer));
00281         NS_ENSURE_SUCCESS(rv,rv);
00282         // make sure we're not deferred to ourself...
00283         if (incomingServer && incomingServer != this) 
00284           rv = incomingServer->GetRootMsgFolder(getter_AddRefs(m_rootMsgFolder));
00285       }
00286     }
00287   }
00288 
00289   NS_IF_ADDREF(*aRootMsgFolder = m_rootMsgFolder);
00290   return rv;
00291 }
00292 
00293 nsresult nsPop3IncomingServer::GetInbox(nsIMsgWindow *msgWindow, nsIMsgFolder **inbox)
00294 {
00295   nsCOMPtr<nsIMsgFolder> rootFolder;
00296   nsresult rv = GetRootMsgFolder(getter_AddRefs(rootFolder));
00297   if(NS_SUCCEEDED(rv) && rootFolder)
00298   {
00299     PRUint32 numFolders;
00300     rv = rootFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, 1, &numFolders, inbox);
00301     if (!*inbox)
00302       return NS_ERROR_NULL_POINTER;
00303   }
00304   nsCOMPtr<nsIMsgLocalMailFolder> localInbox = do_QueryInterface(*inbox, &rv);
00305   if (NS_SUCCEEDED(rv) && localInbox)
00306   {
00307     nsCOMPtr <nsIMsgDatabase> db;
00308     rv = (*inbox)->GetMsgDatabase(msgWindow, getter_AddRefs(db));
00309     if (NS_FAILED(rv))
00310     {
00311       (*inbox)->SetMsgDatabase(nsnull);
00312       (void) localInbox->SetCheckForNewMessagesAfterParsing(PR_TRUE);
00313       // this will cause a reparse of the mail folder.
00314       localInbox->GetDatabaseWithReparse(nsnull, msgWindow, getter_AddRefs(db));
00315       return NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE;
00316     }
00317   }
00318   return rv;
00319 }
00320 
00321 NS_IMETHODIMP nsPop3IncomingServer::PerformBiff(nsIMsgWindow *aMsgWindow)
00322 {
00323   nsresult rv;
00324   nsCOMPtr<nsIPop3Service> pop3Service(do_GetService(kCPop3ServiceCID, &rv));
00325   if (NS_FAILED(rv)) return rv;
00326   
00327   nsCOMPtr<nsIMsgFolder> inbox;
00328   nsCOMPtr<nsIMsgFolder> rootMsgFolder;
00329   nsCOMPtr<nsIUrlListener> urlListener;
00330   rv = GetRootMsgFolder(getter_AddRefs(rootMsgFolder));
00331   NS_ENSURE_SUCCESS(rv,rv);
00332   if (!rootMsgFolder) return NS_ERROR_FAILURE;
00333 
00334   PRUint32 numFolders;
00335   rv = rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, 1,
00336                                          &numFolders,
00337                                          getter_AddRefs(inbox));
00338   NS_ENSURE_SUCCESS(rv,rv);
00339   if (numFolders != 1) return NS_ERROR_FAILURE;
00340 
00341   nsCOMPtr <nsIMsgIncomingServer> server;
00342   inbox->GetServer(getter_AddRefs(server));
00343 
00344   server->SetPerformingBiff(PR_TRUE);
00345 
00346   urlListener = do_QueryInterface(inbox);
00347 
00348   PRBool downloadOnBiff = PR_FALSE;
00349   rv = GetDownloadOnBiff(&downloadOnBiff);
00350   if (downloadOnBiff)
00351   {
00352     nsCOMPtr <nsIMsgLocalMailFolder> localInbox = do_QueryInterface(inbox, &rv);
00353     if (localInbox && NS_SUCCEEDED(rv))
00354     {
00355       PRBool valid = PR_FALSE;
00356       nsCOMPtr <nsIMsgDatabase> db;
00357       rv = inbox->GetMsgDatabase(aMsgWindow, getter_AddRefs(db));
00358       if (NS_SUCCEEDED(rv) && db)
00359         rv = db->GetSummaryValid(&valid);
00360       if (NS_SUCCEEDED(rv) && valid)
00361         rv = pop3Service->GetNewMail(aMsgWindow, urlListener, inbox, this, nsnull);
00362       else
00363       {
00364         PRBool isLocked;
00365         inbox->GetLocked(&isLocked);
00366         if (!isLocked)
00367         {
00368           rv = localInbox->ParseFolder(aMsgWindow, urlListener);
00369         }
00370         if (NS_SUCCEEDED(rv))
00371           rv = localInbox->SetCheckForNewMessagesAfterParsing(PR_TRUE);
00372       }
00373     }
00374   }
00375   else
00376     rv = pop3Service->CheckForNewMail(nsnull, urlListener, inbox, this, nsnull);
00377     // it's important to pass in null for the msg window if we are performing biff
00378         // this makes sure that we don't show any kind of UI during biff.
00379 
00380   return NS_OK;
00381 }
00382 
00383 NS_IMETHODIMP
00384 nsPop3IncomingServer::SetFlagsOnDefaultMailboxes()
00385 {
00386     nsCOMPtr<nsIMsgFolder> rootFolder;
00387     nsresult rv = GetRootFolder(getter_AddRefs(rootFolder));
00388     NS_ENSURE_SUCCESS(rv, rv);
00389 
00390     nsCOMPtr<nsIMsgLocalMailFolder> localFolder =
00391         do_QueryInterface(rootFolder, &rv);
00392     NS_ENSURE_SUCCESS(rv, rv);
00393 
00394     // pop3 gets an inbox, but no queue (unsent messages)
00395     localFolder->SetFlagsOnDefaultMailboxes(MSG_FOLDER_FLAG_INBOX |
00396                                             MSG_FOLDER_FLAG_SENTMAIL |
00397                                             MSG_FOLDER_FLAG_DRAFTS |
00398                                             MSG_FOLDER_FLAG_TEMPLATES |
00399                                             MSG_FOLDER_FLAG_TRASH |
00400                                             MSG_FOLDER_FLAG_JUNK);
00401     return NS_OK;
00402 }
00403     
00404 
00405 NS_IMETHODIMP nsPop3IncomingServer::CreateDefaultMailboxes(nsIFileSpec *path)
00406 {
00407   if (!path) return NS_ERROR_NULL_POINTER;
00408   
00409   (void) path->AppendRelativeUnixPath("Inbox");
00410   nsresult rv = CreateLocalFolder(path, "Inbox");
00411   if (NS_FAILED(rv)) return rv;
00412   return CreateLocalFolder(path, "Trash");
00413 }
00414 
00415 // override this so we can say that deferred accounts can't have messages
00416 // filed to them, which will remove them as targets of all the move/copy
00417 // menu items.
00418 NS_IMETHODIMP
00419 nsPop3IncomingServer::GetCanFileMessagesOnServer(PRBool *aCanFileMessagesOnServer)
00420 {
00421   NS_ENSURE_ARG_POINTER(aCanFileMessagesOnServer);
00422 
00423   nsXPIDLCString deferredToAccount;
00424   GetDeferredToAccount(getter_Copies(deferredToAccount));
00425   *aCanFileMessagesOnServer = deferredToAccount.IsEmpty();
00426   return NS_OK;
00427 }
00428 
00429 
00430 NS_IMETHODIMP
00431 nsPop3IncomingServer::GetCanCreateFoldersOnServer(PRBool *aCanCreateFoldersOnServer)
00432 {
00433   NS_ENSURE_ARG_POINTER(aCanCreateFoldersOnServer);
00434 
00435   nsXPIDLCString deferredToAccount;
00436   GetDeferredToAccount(getter_Copies(deferredToAccount));
00437   *aCanCreateFoldersOnServer = deferredToAccount.IsEmpty();
00438   return NS_OK;
00439 }
00440 
00441 NS_IMETHODIMP nsPop3IncomingServer::DownloadMailFromServers(nsISupportsArray *aServers, 
00442                               nsIMsgWindow *aMsgWindow,
00443                               nsIMsgFolder *aFolder, 
00444                               nsIUrlListener *aUrlListener)
00445 {
00446   nsPop3GetMailChainer *getMailChainer = new nsPop3GetMailChainer;
00447   if (!getMailChainer)
00448     return NS_ERROR_OUT_OF_MEMORY;
00449   getMailChainer->AddRef(); // this object owns itself and releases when done.
00450   return getMailChainer->GetNewMailForServers(aServers, aMsgWindow, aFolder, aUrlListener);
00451 }
00452 
00453 NS_IMETHODIMP nsPop3IncomingServer::GetNewMail(nsIMsgWindow *aMsgWindow, nsIUrlListener *aUrlListener, nsIMsgFolder *aInbox, nsIURI **aResult)
00454 {
00455   nsresult rv;
00456 
00457   nsCOMPtr<nsIPop3Service> pop3Service = do_GetService(kCPop3ServiceCID, &rv);
00458   NS_ENSURE_SUCCESS(rv,rv);
00459   return pop3Service->GetNewMail(aMsgWindow, aUrlListener, aInbox, this, aResult);
00460 }
00461 
00462 // user has clicked get new messages on this server. If other servers defer to this server,
00463 // we need to get new mail for them. But if this server defers to an other server,
00464 // I think we only get new mail for this server.
00465 NS_IMETHODIMP
00466 nsPop3IncomingServer::GetNewMessages(nsIMsgFolder *aFolder, nsIMsgWindow *aMsgWindow, 
00467                       nsIUrlListener *aUrlListener)
00468 {
00469   nsresult rv;
00470 
00471   nsCOMPtr<nsIPop3Service> pop3Service = do_GetService(kCPop3ServiceCID, &rv);
00472   NS_ENSURE_SUCCESS(rv,rv);
00473 
00474   nsCOMPtr <nsIMsgFolder> inbox;
00475   rv = GetInbox(aMsgWindow, getter_AddRefs(inbox));
00476   NS_ENSURE_SUCCESS(rv, rv);
00477   nsCOMPtr <nsIURI> url;
00478   nsCOMPtr <nsIMsgIncomingServer> server;
00479   nsCOMPtr <nsISupportsArray> deferredServers;
00480   nsXPIDLCString deferredToAccount;
00481   GetDeferredToAccount(getter_Copies(deferredToAccount));
00482 
00483   if (deferredToAccount.IsEmpty())
00484   {
00485     aFolder->GetServer(getter_AddRefs(server));
00486     GetDeferredServers(server, getter_AddRefs(deferredServers));
00487   }
00488   PRUint32 numDeferredServers;
00489   if (deferredToAccount.IsEmpty() && deferredServers && NS_SUCCEEDED(deferredServers->Count(&numDeferredServers))
00490     && numDeferredServers > 0)
00491   {
00492     nsPop3GetMailChainer *getMailChainer = new nsPop3GetMailChainer;
00493     getMailChainer->AddRef(); // this object owns itself and releases when done.
00494     nsCOMPtr <nsISupports> supports;
00495     this->QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(supports));
00496     deferredServers->InsertElementAt(supports, 0);
00497     rv = getMailChainer->GetNewMailForServers(deferredServers, aMsgWindow, inbox, aUrlListener);
00498   }
00499   else
00500     rv = pop3Service->GetNewMail(aMsgWindow, aUrlListener, inbox, this, getter_AddRefs(url));
00501   return rv;
00502 }
00503 
00504 NS_IMETHODIMP
00505 nsPop3IncomingServer::GetDownloadMessagesAtStartup(PRBool *getMessagesAtStartup)
00506 {
00507     // GetMessages is not automatically done for pop servers at startup.
00508     // We need to trigger that action. Return true.
00509     *getMessagesAtStartup = PR_TRUE;
00510     return NS_OK;
00511 }
00512 
00513 NS_IMETHODIMP
00514 nsPop3IncomingServer::GetCanBeDefaultServer(PRBool *canBeDefaultServer)
00515 {
00516     *canBeDefaultServer = PR_TRUE;
00517     return NS_OK;
00518 }
00519 
00520 NS_IMETHODIMP
00521 nsPop3IncomingServer::GetCanSearchMessages(PRBool *canSearchMessages)
00522 {
00523   // this will return false if this server is deferred, which is what we want.
00524   return GetCanFileMessagesOnServer(canSearchMessages);
00525 }
00526 
00527 NS_IMETHODIMP
00528 nsPop3IncomingServer::GetOfflineSupportLevel(PRInt32 *aSupportLevel)
00529 {
00530     NS_ENSURE_ARG_POINTER(aSupportLevel);
00531     nsresult rv;
00532     
00533     rv = GetIntValue("offline_support_level", aSupportLevel);
00534     if (*aSupportLevel != OFFLINE_SUPPORT_LEVEL_UNDEFINED) return rv;
00535     
00536     // set default value
00537     *aSupportLevel = OFFLINE_SUPPORT_LEVEL_NONE;
00538     return NS_OK;
00539 }
00540 
00541 NS_IMETHODIMP
00542 nsPop3IncomingServer::SetRunningProtocol(nsIPop3Protocol *aProtocol)
00543 {
00544   NS_ASSERTION(!aProtocol || !m_runningProtocol, "overriding running protocol");
00545   m_runningProtocol = aProtocol;
00546   return NS_OK;
00547 }
00548 
00549 NS_IMETHODIMP nsPop3IncomingServer::GetRunningProtocol(nsIPop3Protocol **aProtocol)
00550 {
00551   NS_ENSURE_ARG_POINTER(aProtocol);
00552   NS_IF_ADDREF(*aProtocol = m_runningProtocol);
00553   return NS_OK;
00554 }
00555 
00556 NS_IMETHODIMP nsPop3IncomingServer::AddUidlToMark(const char *aUidl,
00557        PRInt32 aMark)
00558 {
00559   Pop3UidlEntry *uidlEntry;
00560   nsresult rv = NS_ERROR_OUT_OF_MEMORY;
00561 
00562   uidlEntry = PR_NEWZAP(Pop3UidlEntry);
00563   if (uidlEntry)
00564   {
00565     uidlEntry->uidl = strdup(aUidl);
00566     if (uidlEntry->uidl)
00567     {
00568       uidlEntry->status = (aMark == POP3_DELETE) ? DELETE_CHAR :
00569        (aMark == POP3_FETCH_BODY) ? FETCH_BODY : KEEP;
00570       m_uidlsToMark.AppendElement(uidlEntry);
00571       rv = NS_OK;
00572     } else
00573     {
00574       PR_Free(uidlEntry);
00575     }
00576   }
00577   return rv;
00578 }
00579 
00580 NS_IMETHODIMP nsPop3IncomingServer::MarkMessages()
00581 {
00582   nsresult rv;
00583   if (m_runningProtocol)
00584   {
00585     rv = m_runningProtocol->MarkMessages(&m_uidlsToMark);
00586   }
00587   else
00588   {
00589     nsXPIDLCString hostName;
00590     nsXPIDLCString userName;
00591     nsCOMPtr<nsIFileSpec> localPath;
00592 
00593     GetLocalPath(getter_AddRefs(localPath));
00594   
00595     GetHostName(getter_Copies(hostName));
00596     GetUsername(getter_Copies(userName));
00597     // do it all in one fell swoop
00598     rv = nsPop3Protocol::MarkMsgForHost(hostName, userName, localPath, m_uidlsToMark);
00599   }
00600   PRUint32 count = m_uidlsToMark.Count();
00601   for (PRUint32 i = 0; i < count; i++)
00602   {
00603     Pop3UidlEntry *ue = NS_STATIC_CAST(Pop3UidlEntry*,m_uidlsToMark[i]);
00604     PR_Free(ue->uidl);
00605     PR_Free(ue);
00606   }
00607   m_uidlsToMark.Clear();
00608   return rv;
00609 }
00610 
00611 NS_IMPL_ISUPPORTS1(nsPop3GetMailChainer, nsIUrlListener)
00612 
00613 nsPop3GetMailChainer::nsPop3GetMailChainer()
00614 {
00615 }
00616 nsPop3GetMailChainer::~nsPop3GetMailChainer()
00617 {
00618 }
00619 
00620 nsresult nsPop3GetMailChainer::GetNewMailForServers(nsISupportsArray *servers, nsIMsgWindow *msgWindow,
00621                                 nsIMsgFolder *folderToDownloadTo, nsIUrlListener *listener)
00622 {
00623   NS_ENSURE_ARG_POINTER(folderToDownloadTo);
00624 
00625   m_serversToGetNewMailFor = servers;
00626   m_folderToDownloadTo = folderToDownloadTo;
00627   m_downloadingMsgWindow = msgWindow;
00628   m_listener = listener;
00629   nsCOMPtr <nsIMsgDatabase> destFolderDB;
00630 
00631   nsresult rv = folderToDownloadTo->GetMsgDatabase(msgWindow, getter_AddRefs(destFolderDB));
00632   if (NS_FAILED(rv) || !destFolderDB)
00633   {
00634     nsCOMPtr <nsIMsgLocalMailFolder> localFolder = do_QueryInterface(folderToDownloadTo);
00635     if (localFolder)
00636     {
00637       localFolder->GetDatabaseWithReparse(this, msgWindow, getter_AddRefs(destFolderDB));
00638       return NS_OK;
00639     }
00640   }
00641   return RunNextGetNewMail();
00642 }
00643 
00644 NS_IMETHODIMP
00645 nsPop3GetMailChainer::OnStartRunningUrl(nsIURI *url)
00646 {
00647   return NS_OK;
00648 }
00649 
00650 NS_IMETHODIMP
00651 nsPop3GetMailChainer::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
00652 {
00653   return RunNextGetNewMail();
00654 }
00655 
00656 nsresult nsPop3GetMailChainer::RunNextGetNewMail()
00657 {
00658   nsresult rv;
00659   PRUint32 numServersLeft;
00660   m_serversToGetNewMailFor->Count(&numServersLeft);
00661 
00662   for (; numServersLeft > 0;)
00663   {
00664     nsCOMPtr <nsIPop3IncomingServer> popServer (do_QueryElementAt(m_serversToGetNewMailFor, 0));
00665     m_serversToGetNewMailFor->RemoveElementAt(0);
00666     numServersLeft--;
00667     if (popServer)
00668     {
00669       PRBool deferGetNewMail = PR_FALSE;
00670       nsCOMPtr <nsIMsgIncomingServer> downloadingToServer;
00671       m_folderToDownloadTo->GetServer(getter_AddRefs(downloadingToServer));
00672       popServer->GetDeferGetNewMail(&deferGetNewMail);
00673       nsCOMPtr <nsIMsgIncomingServer> server = do_QueryInterface(popServer);
00674       if (deferGetNewMail || downloadingToServer == server)
00675       {
00676         // have to call routine that just gets mail for one server,
00677         // and ignores deferred servers...
00678         if (server)
00679         {
00680           nsCOMPtr <nsIURI> url;
00681           nsCOMPtr<nsIPop3Service> pop3Service = do_GetService(kCPop3ServiceCID, &rv);
00682           NS_ENSURE_SUCCESS(rv,rv);
00683           return pop3Service->GetNewMail(m_downloadingMsgWindow, this, m_folderToDownloadTo, popServer, getter_AddRefs(url));
00684         }
00685       }
00686     }
00687   }
00688   rv = (m_listener) ? m_listener->OnStopRunningUrl(nsnull, NS_OK) 
00689                          : NS_OK;
00690   Release(); // release ref to ourself.
00691   return rv;
00692 }
00693