diff --git a/mailnews/imap/public/nsIImapIncomingServer.idl b/mailnews/imap/public/nsIImapIncomingServer.idl index d182ec7ec31..1c823f95967 100644 --- a/mailnews/imap/public/nsIImapIncomingServer.idl +++ b/mailnews/imap/public/nsIImapIncomingServer.idl @@ -63,6 +63,7 @@ interface nsIImapIncomingServer : nsISupports { attribute boolean fetchByChunks; attribute boolean mimePartsOnDemand; attribute boolean isAOLServer; + attribute boolean aOLMailboxView; void GetImapConnectionAndLoadUrl(in nsIEventQueue aClientEventQueue, in nsIImapUrl aImapUrl, in nsISupports aConsumer); diff --git a/mailnews/imap/src/nsImapIncomingServer.cpp b/mailnews/imap/src/nsImapIncomingServer.cpp index d31331ee906..f1696a4cb86 100644 --- a/mailnews/imap/src/nsImapIncomingServer.cpp +++ b/mailnews/imap/src/nsImapIncomingServer.cpp @@ -124,7 +124,7 @@ NS_IMETHODIMP nsImapIncomingServer::SetKey(const char * aKey) // override nsMsg if (NS_FAILED(rv)) return rv; hostSession->AddHostToList(aKey); - nsMsgImapDeleteModel deleteModel; + nsMsgImapDeleteModel deleteModel = nsMsgImapDeleteModels::MoveToTrash; // default to trash GetDeleteModel(&deleteModel); hostSession->SetDeleteIsMoveToTrashForHost(aKey, deleteModel == nsMsgImapDeleteModels::MoveToTrash); hostSession->SetShowDeletedMessagesForHost(aKey, deleteModel == nsMsgImapDeleteModels::IMAPDelete); @@ -224,6 +224,9 @@ NS_IMPL_SERVERPREF_BOOL(nsImapIncomingServer, FetchByChunks, NS_IMPL_SERVERPREF_BOOL(nsImapIncomingServer, MimePartsOnDemand, "mime_parts_on_demand"); +NS_IMPL_SERVERPREF_BOOL(nsImapIncomingServer, AOLMailboxView, + "aol_mailbox_view"); + NS_IMETHODIMP nsImapIncomingServer::GetIsAOLServer(PRBool *aBool) { @@ -249,41 +252,43 @@ nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue * aClientEventQu nsIImapUrl* aImapUrl, nsISupports* aConsumer) { - nsresult rv = NS_OK; - nsCOMPtr aProtocol; - - rv = CreateImapConnection(aClientEventQueue, aImapUrl, getter_AddRefs(aProtocol)); - if (NS_FAILED(rv)) return rv; + nsresult rv = NS_OK; + nsCOMPtr aProtocol; + + rv = CreateImapConnection(aClientEventQueue, aImapUrl, getter_AddRefs(aProtocol)); + if (NS_FAILED(rv)) return rv; nsCOMPtr mailnewsurl = do_QueryInterface(aImapUrl, &rv); - if (aProtocol) + if (aProtocol) + { + rv = aProtocol->LoadUrl(mailnewsurl, aConsumer); + // *** jt - in case of the time out situation or the connection gets + // terminated by some unforseen problems let's give it a second chance + // to run the url + if (NS_FAILED(rv)) { + NS_ASSERTION(PR_FALSE, "shouldn't get an error loading url"); rv = aProtocol->LoadUrl(mailnewsurl, aConsumer); - // *** jt - in case of the time out situation or the connection gets - // terminated by some unforseen problems let's give it a second chance - // to run the url - if (NS_FAILED(rv)) - { - rv = aProtocol->LoadUrl(mailnewsurl, aConsumer); - } - else - { - // *** jt - alert user that error has occurred - } } else - { // unable to get an imap connection to run the url; add to the url - // queue - PR_CEnterMonitor(this); - nsCOMPtr supports(do_QueryInterface(aImapUrl)); - if (supports) - m_urlQueue->AppendElement(supports); - m_urlConsumers.AppendElement((void*)aConsumer); - NS_IF_ADDREF(aConsumer); - PR_CExitMonitor(this); - } + { + // *** jt - alert user that error has occurred + } + } + else + { // unable to get an imap connection to run the url; add to the url + // queue + PR_CEnterMonitor(this); + nsCOMPtr supports(do_QueryInterface(aImapUrl)); +// printf("queueing imap url \n"); + if (supports) + m_urlQueue->AppendElement(supports); + m_urlConsumers.AppendElement((void*)aConsumer); + NS_IF_ADDREF(aConsumer); + PR_CExitMonitor(this); + } - return rv; + return rv; } // checks to see if there are any queued urls on this incoming server, @@ -291,49 +296,53 @@ nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue * aClientEventQu NS_IMETHODIMP nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult) { - PRUint32 cnt = 0; - nsresult rv = NS_OK; + PRUint32 cnt = 0; + nsresult rv = NS_OK; PRBool urlRun = PR_FALSE; - PR_CEnterMonitor(this); - m_urlQueue->Count(&cnt); - if (cnt > 0) + PR_CEnterMonitor(this); + m_urlQueue->Count(&cnt); + +// printf("loading next url, cnt = %ld\n", cnt); + + if (cnt > 0) + { + nsCOMPtr + aSupport(getter_AddRefs(m_urlQueue->ElementAt(0))); + nsCOMPtr + aImapUrl(do_QueryInterface(aSupport, &rv)); + + if (aImapUrl) { - nsCOMPtr - aSupport(getter_AddRefs(m_urlQueue->ElementAt(0))); - nsCOMPtr - aImapUrl(do_QueryInterface(aSupport, &rv)); + nsISupports *aConsumer = + (nsISupports*)m_urlConsumers.ElementAt(0); - if (aImapUrl) - { - nsISupports *aConsumer = - (nsISupports*)m_urlConsumers.ElementAt(0); + NS_IF_ADDREF(aConsumer); + + nsCOMPtr protocolInstance ; + rv = CreateImapConnection(nsnull, aImapUrl, + getter_AddRefs(protocolInstance)); + if (NS_SUCCEEDED(rv) && protocolInstance) + { + nsCOMPtr url = do_QueryInterface(aImapUrl, &rv); + if (NS_SUCCEEDED(rv) && url) + { + rv = protocolInstance->LoadUrl(url, aConsumer); + NS_ASSERTION(NS_SUCCEEDED(rv), "failed running queued url"); + urlRun = PR_TRUE; + } + m_urlQueue->RemoveElementAt(0); + m_urlConsumers.RemoveElementAt(0); + } - NS_IF_ADDREF(aConsumer); - - nsCOMPtr protocolInstance ; - rv = CreateImapConnection(nsnull, aImapUrl, - getter_AddRefs(protocolInstance)); - if (NS_SUCCEEDED(rv) && protocolInstance) - { - nsCOMPtr url = do_QueryInterface(aImapUrl, &rv); - if (NS_SUCCEEDED(rv) && url) - { - rv = protocolInstance->LoadUrl(url, aConsumer); - urlRun = PR_TRUE; - } - m_urlQueue->RemoveElementAt(0); - m_urlConsumers.RemoveElementAt(0); - } - - NS_IF_RELEASE(aConsumer); - } + NS_IF_RELEASE(aConsumer); } + } if (aResult) *aResult = urlRun; - PR_CExitMonitor(this); - return rv; + PR_CExitMonitor(this); + return rv; } @@ -397,65 +406,72 @@ nsImapIncomingServer::CreateImapConnection(nsIEventQueue *aEventQueue, nsIImapProtocol ** aImapConnection) { nsresult rv = NS_OK; - PRBool canRunUrl = PR_FALSE; - PRBool hasToWait = PR_FALSE; + PRBool canRunUrlImmediately = PR_FALSE; + PRBool canRunButBusy = PR_FALSE; nsCOMPtr connection; - nsCOMPtr freeConnection; - PRBool isBusy = PR_FALSE; - PRBool isInboxConnection = PR_FALSE; + nsCOMPtr freeConnection; + PRBool isBusy = PR_FALSE; + PRBool isInboxConnection = PR_FALSE; nsXPIDLCString redirectorType; - PR_CEnterMonitor(this); + PR_CEnterMonitor(this); GetRedirectorType(getter_Copies(redirectorType)); PRBool redirectLogon = ((const char *) redirectorType && nsCRT::strlen((const char *) redirectorType) > 0); - PRInt32 maxConnections = 5; // default to be five - rv = GetMaximumConnectionsNumber(&maxConnections); - if (NS_FAILED(rv) || maxConnections == 0) - { - maxConnections = 5; - rv = SetMaximumConnectionsNumber(maxConnections); - } - else if (maxConnections < 2) - { // forced to use at least 2 - maxConnections = 2; - rv = SetMaximumConnectionsNumber(maxConnections); - } + PRInt32 maxConnections = 5; // default to be five + rv = GetMaximumConnectionsNumber(&maxConnections); + if (NS_FAILED(rv) || maxConnections == 0) + { + maxConnections = 5; + rv = SetMaximumConnectionsNumber(maxConnections); + } + else if (maxConnections < 2) + { // forced to use at least 2 + maxConnections = 2; + rv = SetMaximumConnectionsNumber(maxConnections); + } - *aImapConnection = nsnull; + *aImapConnection = nsnull; // iterate through the connection cache for a connection that can handle this url. PRUint32 cnt; - nsCOMPtr aSupport; + nsCOMPtr aSupport; - rv = m_connectionCache->Count(&cnt); - if (NS_FAILED(rv)) return rv; - for (PRUint32 i = 0; i < cnt && !canRunUrl && !hasToWait; i++) + rv = m_connectionCache->Count(&cnt); + if (NS_FAILED(rv)) return rv; + // loop until we find a connection that can run the url, or doesn't have to wait? + for (PRUint32 i = 0; i < cnt && !canRunUrlImmediately && !canRunButBusy; i++) { - aSupport = getter_AddRefs(m_connectionCache->ElementAt(i)); - connection = do_QueryInterface(aSupport); + aSupport = getter_AddRefs(m_connectionCache->ElementAt(i)); + connection = do_QueryInterface(aSupport); if (connection) - rv = connection->CanHandleUrl(aImapUrl, &canRunUrl, &hasToWait); - if (NS_FAILED(rv)) - { - connection = null_nsCOMPtr(); - continue; - } - if (!freeConnection && !canRunUrl && !hasToWait && connection) - { - rv = connection->IsBusy(&isBusy, &isInboxConnection); - if (NS_FAILED(rv)) continue; - if (!isBusy && !isInboxConnection) - freeConnection = connection; - } - } - - if (ConnectionTimeOut(connection)) + rv = connection->CanHandleUrl(aImapUrl, &canRunUrlImmediately, &canRunButBusy); + if (NS_FAILED(rv)) + { connection = null_nsCOMPtr(); - if (ConnectionTimeOut(freeConnection)) - freeConnection = null_nsCOMPtr(); + continue; + } + // if we haven't found a free connection, and this connection + // is wrong, but it's not busy. + if (!freeConnection && !canRunUrlImmediately && !canRunButBusy && connection) + { + rv = connection->IsBusy(&isBusy, &isInboxConnection); + if (NS_FAILED(rv)) + continue; + if (!isBusy && !isInboxConnection) + freeConnection = connection; + } + // don't leave this loop with connection set if we can't use it! + if (!canRunButBusy && !canRunUrlImmediately) + connection = null_nsCOMPtr(); + } + + if (ConnectionTimeOut(connection)) + connection = null_nsCOMPtr(); + if (ConnectionTimeOut(freeConnection)) + freeConnection = null_nsCOMPtr(); - if (redirectLogon && (!connection || !canRunUrl)) + if (redirectLogon && (!connection || !canRunUrlImmediately)) { // here's where we'd start the asynchronous process of requesting a connection to the // AOL Imap server and getting back an ip address, port #, and cookie. @@ -470,34 +486,34 @@ nsImapIncomingServer::CreateImapConnection(nsIEventQueue *aEventQueue, rv = mailnewsUrl->GetMsgWindow(getter_AddRefs(aMsgWindow)); RequestOverrideInfo(aMsgWindow); - hasToWait = PR_TRUE; + canRunButBusy = PR_TRUE; } } // if we got here and we have a connection, then we should return it! - if (canRunUrl && connection) + if (canRunUrlImmediately && connection) { *aImapConnection = connection; NS_IF_ADDREF(*aImapConnection); } - else if (hasToWait) - { - // do nothing; return NS_OK; for queuing - } + else if (canRunButBusy) + { + // do nothing; return NS_OK; for queuing + } else if (cnt < ((PRUint32)maxConnections) && aEventQueue) { rv = CreateProtocolInstance(aEventQueue, aImapConnection); } - else if (freeConnection) - { - *aImapConnection = freeConnection; - NS_IF_ADDREF(*aImapConnection); - } - else // cannot get anyone to handle the url queue it - { - // queue the url - } + else if (freeConnection) + { + *aImapConnection = freeConnection; + NS_IF_ADDREF(*aImapConnection); + } + else // cannot get anyone to handle the url queue it + { + // queue the url + } - PR_CExitMonitor(this); + PR_CExitMonitor(this); return rv; } @@ -1439,7 +1455,7 @@ NS_IMETHODIMP nsImapIncomingServer::PseudoInterruptMsgLoad(nsIImapUrl *aImapUrl, { nsresult rv = NS_OK; PRBool canRunUrl = PR_FALSE; - PRBool hasToWait = PR_FALSE; + PRBool canRunButBusy = PR_FALSE; nsCOMPtr connection; PR_CEnterMonitor(this); @@ -1451,7 +1467,7 @@ NS_IMETHODIMP nsImapIncomingServer::PseudoInterruptMsgLoad(nsIImapUrl *aImapUrl, rv = m_connectionCache->Count(&cnt); if (NS_FAILED(rv)) return rv; - for (PRUint32 i = 0; i < cnt && !canRunUrl && !hasToWait; i++) + for (PRUint32 i = 0; i < cnt && !canRunUrl && !canRunButBusy; i++) { aSupport = getter_AddRefs(m_connectionCache->ElementAt(i)); connection = do_QueryInterface(aSupport); diff --git a/mailnews/imap/src/nsImapIncomingServer.h b/mailnews/imap/src/nsImapIncomingServer.h index 368bce74308..7241461199f 100644 --- a/mailnews/imap/src/nsImapIncomingServer.h +++ b/mailnews/imap/src/nsImapIncomingServer.h @@ -30,6 +30,7 @@ #include "nsIImapServerSink.h" #include "nsIStringBundle.h" #include "nsIMsgLogonRedirector.h" +#include "nsINntpProtocol.h" /* get some implementation from nsMsgIncomingServer */ class nsImapIncomingServer : public nsMsgIncomingServer, diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index 6f94ea1b407..dcb64fb1ab9 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -758,6 +758,8 @@ NS_IMETHODIMP nsImapMailFolder::GetHierarchyDelimiter(PRUnichar *aHierarchyDelim NS_IMETHODIMP nsImapMailFolder::SetBoxFlags(PRInt32 aBoxFlags) { + ReadDBFolderInfo(PR_FALSE); + m_boxFlags = aBoxFlags; PRUint32 newFlags = mFlags; @@ -771,10 +773,11 @@ NS_IMETHODIMP nsImapMailFolder::SetBoxFlags(PRInt32 aBoxFlags) newFlags |= MSG_FOLDER_FLAG_TRASH; else newFlags &= ~MSG_FOLDER_FLAG_TRASH; - if (m_boxFlags & kImapSent) - newFlags |= MSG_FOLDER_FLAG_SENTMAIL; - else - newFlags &= ~MSG_FOLDER_FLAG_SENTMAIL; + // imap code doesn't seem to be setting this flag, so we shouldn't be either :-( +// if (m_boxFlags & kImapSent) +// newFlags |= MSG_FOLDER_FLAG_SENTMAIL; +// else +// newFlags &= ~MSG_FOLDER_FLAG_SENTMAIL; if (m_boxFlags & kNoselect) newFlags |= MSG_FOLDER_FLAG_IMAP_NOSELECT; else @@ -1161,6 +1164,8 @@ NS_IMETHODIMP nsImapMailFolder::ReadFromFolderCacheElem(nsIMsgFolderCacheElement rv = element->GetStringProperty("onlineName", getter_Copies(onlineName)); if (NS_SUCCEEDED(rv) && (const char *) onlineName && nsCRT::strlen((const char *) onlineName)) m_onlineFolderName.Assign(onlineName); + if (!nsCRT::strcasecmp((const char *) onlineName, "Sent")) + printf("loading folder cache elem for %s flags = %lx", (const char *) onlineName, mFlags); return rv; } @@ -1415,6 +1420,8 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages, rv = rootFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_TRASH, 1, &numFolders, getter_AddRefs(trashFolder)); + NS_ASSERTION(NS_SUCCEEDED(rv) && trashFolder != 0, "couldn't find trash"); + // if we can't find the trash, we'll just have to do an imap delete and pretend this is the trash if (NS_FAILED(rv) || !trashFolder) deleteImmediatelyNoTrash = PR_TRUE; @@ -3074,82 +3081,89 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode) mailUrl->GetMsgWindow(getter_AddRefs(aWindow)); if (session) session->IsFolderOpenInWindow(this, &folderOpen); +#ifdef DEBUG_bienvenu1 + nsXPIDLCString urlSpec; + aUrl->GetSpec(getter_Copies(urlSpec)); + printf("stop running url %s\n", (const char *) urlSpec); +#endif - if (imapUrl) + if (imapUrl) + { + nsImapAction imapAction = nsIImapUrl::nsImapTest; + imapUrl->GetImapAction(&imapAction); + switch(imapAction) { - nsImapAction imapAction = nsIImapUrl::nsImapTest; - imapUrl->GetImapAction(&imapAction); - switch(imapAction) + case nsIImapUrl::nsImapDeleteMsg: + case nsIImapUrl::nsImapOnlineMove: + case nsIImapUrl::nsImapOnlineCopy: + if (m_copyState) + { + if (NS_SUCCEEDED(aExitCode)) { - case nsIImapUrl::nsImapDeleteMsg: - case nsIImapUrl::nsImapOnlineMove: - case nsIImapUrl::nsImapOnlineCopy: - if (m_copyState) + if (folderOpen) + UpdateFolder(aWindow); + else + UpdatePendingCounts(PR_TRUE, PR_FALSE); + if (m_copyState->m_isMove) + { + nsCOMPtr srcFolder; + srcFolder = + do_QueryInterface(m_copyState->m_srcSupport, + &rv); + nsCOMPtr srcDB; + if (NS_SUCCEEDED(rv)) + rv = srcFolder->GetMsgDatabase(aWindow, + getter_AddRefs(srcDB)); + if (NS_SUCCEEDED(rv) && srcDB) { - if (NS_SUCCEEDED(aExitCode)) - { - if (folderOpen) - UpdateFolder(aWindow); - else - UpdatePendingCounts(PR_TRUE, PR_FALSE); - if (m_copyState->m_isMove) - { - nsCOMPtr srcFolder; - srcFolder = - do_QueryInterface(m_copyState->m_srcSupport, - &rv); - nsCOMPtr srcDB; - if (NS_SUCCEEDED(rv)) - rv = srcFolder->GetMsgDatabase(aWindow, - getter_AddRefs(srcDB)); - if (NS_SUCCEEDED(rv) && srcDB) - { - nsCOMPtr msgTxn; - nsMsgKeyArray srcKeyArray; - msgTxn = - do_QueryInterface(m_copyState->m_undoMsgTxn); - if (msgTxn) - msgTxn->GetSrcKeyArray(srcKeyArray); - srcDB->DeleteMessages(&srcKeyArray, nsnull); - NotifyDeleteOrMoveMessagesCompleted(srcFolder); - } - } - if (m_transactionManager) - m_transactionManager->Do(m_copyState->m_undoMsgTxn); - } - ClearCopyState(aExitCode); + nsCOMPtr msgTxn; + nsMsgKeyArray srcKeyArray; + msgTxn = + do_QueryInterface(m_copyState->m_undoMsgTxn); + if (msgTxn) + msgTxn->GetSrcKeyArray(srcKeyArray); + srcDB->DeleteMessages(&srcKeyArray, nsnull); + NotifyDeleteOrMoveMessagesCompleted(srcFolder); } - break; - case nsIImapUrl::nsImapAddMsgFlags: - // this isn't really right - we'd like to know we were - // deleting a message to start with, but it probably - // won't do any harm. - NotifyDeleteOrMoveMessagesCompleted(this); - - break; - case nsIImapUrl::nsImapAppendMsgFromFile: - case nsIImapUrl::nsImapAppendDraftFromFile: - if (m_copyState) - { - if (folderOpen) - UpdateFolder(aWindow); - else - UpdatePendingCounts(PR_TRUE, PR_FALSE); - m_copyState->m_curIndex++; - if (m_copyState->m_curIndex >= m_copyState->m_totalCount) - { - if (m_transactionManager && m_copyState->m_undoMsgTxn) - m_transactionManager->Do(m_copyState->m_undoMsgTxn); - ClearCopyState(aExitCode); - } - } - break; - case nsIImapUrl::nsImapRenameFolder: - break; - default: - break; + } + if (m_transactionManager) + m_transactionManager->Do(m_copyState->m_undoMsgTxn); } + ClearCopyState(aExitCode); + } + break; + case nsIImapUrl::nsImapAddMsgFlags: + // this isn't really right - we'd like to know we were + // deleting a message to start with, but it probably + // won't do any harm. + NotifyDeleteOrMoveMessagesCompleted(this); + + break; + case nsIImapUrl::nsImapAppendMsgFromFile: + case nsIImapUrl::nsImapAppendDraftFromFile: + if (m_copyState) + { + if (folderOpen) + UpdateFolder(aWindow); + else + UpdatePendingCounts(PR_TRUE, PR_FALSE); + m_copyState->m_curIndex++; + if (m_copyState->m_curIndex >= m_copyState->m_totalCount) + { + if (m_transactionManager && m_copyState->m_undoMsgTxn) + m_transactionManager->Do(m_copyState->m_undoMsgTxn); + ClearCopyState(aExitCode); + } + else + NS_ASSERTION(PR_FALSE, "not clearing copy state"); + } + break; + case nsIImapUrl::nsImapRenameFolder: + break; + default: + break; } + } // give base class a chance to send folder loaded notification... rv = nsMsgDBFolder::OnStopRunningUrl(aUrl, aExitCode); // query it for a mailnews interface for now.... @@ -3785,6 +3799,11 @@ nsImapMailFolder::CopyMessages(nsIMsgFolder* srcFolder, NS_GET_IID(nsImapMoveCopyMsgTxn), getter_AddRefs(m_copyState->m_undoMsgTxn) ); } + else + { + NS_ASSERTION(PR_FALSE, "online copy failed"); + ClearCopyState(rv); + } done: return rv; @@ -3943,9 +3962,10 @@ nsImapMailFolder::InitCopyState(nsISupports* srcSupport, PRBool selectedState, nsIMsgCopyServiceListener* listener) { - nsresult rv = NS_ERROR_NULL_POINTER; + nsresult rv = NS_OK; - if (!srcSupport || !messages) return rv; + if (!srcSupport || !messages) return NS_ERROR_NULL_POINTER; +// NS_ASSERTION(!m_copyState, "move/copy already in progress"); if (m_copyState) return NS_ERROR_FAILURE; nsImapMailCopyState* copyState = new nsImapMailCopyState(); diff --git a/mailnews/imap/src/nsImapProtocol.cpp b/mailnews/imap/src/nsImapProtocol.cpp index 3721d54f41b..d60d2a48557 100644 --- a/mailnews/imap/src/nsImapProtocol.cpp +++ b/mailnews/imap/src/nsImapProtocol.cpp @@ -428,12 +428,14 @@ nsImapProtocol::GetImapServerKey() void nsImapProtocol::SetupSinkProxy() { + nsresult res = NS_ERROR_FAILURE; + NS_ASSERTION(!m_imapMiscellaneousSink, "shouldn't be non-null here"); + if (m_runningUrl) { NS_ASSERTION(m_sinkEventQueue && m_thread, "fatal... null sink event queue or thread"); - nsresult res; - nsCOMPtr proxyManager(do_GetService(kProxyObjectManagerCID)); + nsCOMPtr proxyManager(do_GetService(kProxyObjectManagerCID, &res)); if (proxyManager) // if we don't get one of these are as good as dead... { if (!m_imapMailFolderSink) @@ -484,6 +486,7 @@ nsImapProtocol::SetupSinkProxy() m_thread); m_imapMiscellaneousSink = do_QueryInterface(miscSink); } + NS_ASSERTION(NS_SUCCEEDED(res), "couldn't get proxies"); } if (!m_imapServerSink) { @@ -495,9 +498,13 @@ nsImapProtocol::SetupSinkProxy() aImapServerSink, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs(m_imapServerSink)); + NS_ASSERTION(NS_SUCCEEDED(res), "couldn't get proxies"); } } + else + NS_ASSERTION(PR_FALSE, "can't get proxy service"); } + NS_ASSERTION(NS_SUCCEEDED(res), "couldn't get proxies"); } // Setup With Url is intended to set up data which is held on a PER URL basis and not @@ -849,13 +856,13 @@ nsImapProtocol::ImapThreadMainLoop() { PRIntervalTime sleepTime = kImapSleepTime; // ****** please implement PR_LOG 'ing ****** - while (ImapThreadIsRunning() && !DeathSignalReceived()) - { - // if we are making our first pass through this loop and - // we already have a url to process then jump right in and - // process the current url. Don't try to wait for the monitor - // the first time because it may have already been signaled. - // But make sure we have a channel first, or ProcessCurrentUrl will fail. + while (ImapThreadIsRunning() && !DeathSignalReceived()) + { + // if we are making our first pass through this loop and + // we already have a url to process then jump right in and + // process the current url. Don't try to wait for the monitor + // the first time because it may have already been signaled. + // But make sure we have a channel first, or ProcessCurrentUrl will fail. if (TestFlag(IMAP_FIRST_PASS_IN_THREAD) && m_runningUrl && m_channel) { // if we launched another url, just loop around and process it. @@ -870,24 +877,25 @@ nsImapProtocol::ImapThreadMainLoop() PRStatus err; - err = PR_Wait(m_urlReadyToRunMonitor, sleepTime); + err = PR_Wait(m_urlReadyToRunMonitor, sleepTime); - PR_ExitMonitor(m_urlReadyToRunMonitor); - if (err == PR_FAILURE && PR_PENDING_INTERRUPT_ERROR == PR_GetError()) + PR_ExitMonitor(m_urlReadyToRunMonitor); + if (err == PR_FAILURE && PR_PENDING_INTERRUPT_ERROR == PR_GetError()) { + printf("error waiting for monitor\n"); break; } -// m_eventQueue->ProcessPendingEvents(); -// m_sinkEventQueue->ProcessPendingEvents(); + // m_eventQueue->ProcessPendingEvents(); + // m_sinkEventQueue->ProcessPendingEvents(); if (m_nextUrlReadyToRun && m_runningUrl) + { + m_nextUrlReadyToRun = PR_FALSE; ProcessCurrentURL(); - - m_nextUrlReadyToRun = PR_FALSE; - } - m_imapThreadIsRunning = PR_FALSE; + } + m_imapThreadIsRunning = PR_FALSE; } void nsImapProtocol::EstablishServerConnection() @@ -1028,7 +1036,11 @@ PRBool nsImapProtocol::ProcessCurrentURL() m_channel->AsyncRead(this /* stream observer */, nsnull); SetFlag(IMAP_CONNECTION_IS_OPEN); } - + + NS_ASSERTION(m_imapMiscellaneousSink, "null sink"); + if (!m_imapMiscellaneousSink) + SetupSinkProxy(); // try this again. Evil, but I'm desperate. + // we used to check if the current running url was // Reinitialize the parser GetServerStateParser().InitializeState(); @@ -1037,6 +1049,11 @@ PRBool nsImapProtocol::ProcessCurrentURL() // acknowledge that we are running the url now.. nsresult rv = NS_OK; nsCOMPtr mailnewsurl = do_QueryInterface(m_runningUrl, &rv); +#ifdef DEBUG_bienvenu1 + nsXPIDLCString urlSpec; + mailnewsurl->GetSpec(getter_Copies(urlSpec)); + printf("processing url %s\n", (const char *) urlSpec); +#endif if (NS_SUCCEEDED(rv) && mailnewsurl && m_imapMiscellaneousSink) { m_imapMiscellaneousSink->SetUrlState(this, mailnewsurl, PR_TRUE, @@ -1121,6 +1138,8 @@ PRBool nsImapProtocol::ProcessCurrentURL() // url. WaitForFEEventCompletion(); } + else + NS_ASSERTION(PR_FALSE, "missing url or sink"); // if we are set up as a channel, we should notify our channel listener that we are starting... // so pass in ourself as the channel and not the underlying socket or file channel the protocol @@ -1137,6 +1156,10 @@ PRBool nsImapProtocol::ProcessCurrentURL() WaitForFEEventCompletion(); } +#ifdef DEBUG_bienvenu1 + mailnewsurl->GetSpec(getter_Copies(urlSpec)); + printf("end processing url %s\n", (const char *) urlSpec); +#endif // this is so hokey...we MUST clear any local references to the url // BEFORE calling ReleaseUrlState mailnewsurl = nsnull; @@ -1144,11 +1167,12 @@ PRBool nsImapProtocol::ProcessCurrentURL() // release the url as we are done with it... ReleaseUrlState(); ResetProgressInfo(); + m_urlInProgress = PR_FALSE; // now try queued urls, now that we've released this connection. if (m_imapServerSink && GetConnectionStatus() >= 0) { rv = m_imapServerSink->LoadNextQueuedUrl(&anotherUrlRun); - SetFlag(IMAP_FIRST_PASS_IN_THREAD); + SetFlag(IMAP_FIRST_PASS_IN_THREAD); } if (GetConnectionStatus() < 0) @@ -1342,7 +1366,14 @@ nsresult nsImapProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) nsresult rv = NS_OK; if (aURL) { +#ifdef DEBUG_bienvenu1 + nsXPIDLCString urlSpec; + aURL->GetSpec(getter_Copies(urlSpec)); + printf("loading url %s\n", (const char *) urlSpec); +#endif + m_urlInProgress = PR_TRUE; rv = SetupWithUrl(aURL, aConsumer); + NS_ASSERTION(NS_SUCCEEDED(rv), "error setting up imap url"); if (NS_FAILED(rv)) return rv; SetupSinkProxy(); // generate proxies for all of the event sinks in the url m_lastActiveTime = PR_Now(); @@ -1364,6 +1395,9 @@ nsresult nsImapProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) PR_ExitMonitor(m_urlReadyToRunMonitor); } // if we have an imap url and a transport + else + NS_ASSERTION(PR_FALSE, "missing channel or running url"); + } // if we received a url! return rv; @@ -1375,30 +1409,33 @@ NS_IMETHODIMP nsImapProtocol::IsBusy(PRBool *aIsConnectionBusy, if (!aIsConnectionBusy || !isInboxConnection) return NS_ERROR_NULL_POINTER; NS_LOCK_INSTANCE(); - nsresult rv = NS_OK; + nsresult rv = NS_OK; *aIsConnectionBusy = PR_FALSE; - *isInboxConnection = PR_FALSE; - if (!m_channel) - { - // ** jt -- something is really wrong kill the thread - TellThreadToDie(PR_FALSE); - rv = NS_ERROR_FAILURE; - } - else - { - if (m_runningUrl) // do we have a url? That means we're working on - // it... - *aIsConnectionBusy = PR_TRUE; - if (GetServerStateParser().GetSelectedMailboxName() && - PL_strcasecmp(GetServerStateParser().GetSelectedMailboxName(), - "Inbox") == 0) - *isInboxConnection = PR_TRUE; - - } + *isInboxConnection = PR_FALSE; + if (!m_channel) + { + // ** jt -- something is really wrong kill the thread + TellThreadToDie(PR_FALSE); + rv = NS_ERROR_FAILURE; + } + else + { + if (m_urlInProgress) // do we have a url? That means we're working on it... + *aIsConnectionBusy = PR_TRUE; + + if (GetServerStateParser().GetSelectedMailboxName() && + PL_strcasecmp(GetServerStateParser().GetSelectedMailboxName(), + "Inbox") == 0) + *isInboxConnection = PR_TRUE; + + } NS_UNLOCK_INSTANCE(); return rv; } +// canRunUrl means the connection is not busy, and is in the selcted state +// for the desired folder (or authenticated). +// has to wait means it's in the right selected state, but busy. NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl, PRBool * aCanRunUrl, PRBool * hasToWait) @@ -1409,110 +1446,115 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl, NS_LOCK_INSTANCE(); *aCanRunUrl = PR_FALSE; // assume guilty until proven otherwise... - *hasToWait = PR_FALSE; + *hasToWait = PR_FALSE; - PRBool isBusy = PR_FALSE; - PRBool isInboxConnection = PR_FALSE; + PRBool isBusy = PR_FALSE; + PRBool isInboxConnection = PR_FALSE; - if (!m_channel) + if (!m_channel) + { + // *** jt -- something is really wrong; it could be the dialer gave up + // the connection or ip binding has been release by the operating + // system; tell thread to die and return error failure + TellThreadToDie(PR_FALSE); + rv = NS_ERROR_FAILURE; + } + else + { + IsBusy(&isBusy, &isInboxConnection); + + PRBool inSelectedState = GetServerStateParser().GetIMAPstate() == + nsImapServerResponseParser::kFolderSelected; + + nsCString curUrlFolderName; + if (inSelectedState) { - // *** jt -- something is really wrong; it could be the dialer gave up - // the connection or ip binding has been release by the operating - // system; tell thread to die and return error failure - TellThreadToDie(PR_FALSE); - rv = NS_ERROR_FAILURE; + curUrlFolderName = + GetServerStateParser().GetSelectedMailboxName(); } - else + else if (isBusy) { - IsBusy(&isBusy, &isInboxConnection); - - PRBool inSelectedState = GetServerStateParser().GetIMAPstate() == - nsImapServerResponseParser::kFolderSelected; - - nsCString curUrlFolderName; - if (inSelectedState) + nsImapState curUrlImapState; + m_runningUrl->GetRequiredImapState(&curUrlImapState); + if (curUrlImapState == nsIImapUrl::nsImapSelectedState) { - curUrlFolderName = - GetServerStateParser().GetSelectedMailboxName(); - } - else if (isBusy) - { - nsImapState curUrlImapState; - m_runningUrl->GetRequiredImapState(&curUrlImapState); - if (curUrlImapState == nsIImapUrl::nsImapSelectedState) - { - curUrlFolderName = OnCreateServerSourceFolderPathString(); - inSelectedState = PR_TRUE; - } + curUrlFolderName = OnCreateServerSourceFolderPathString(); + inSelectedState = PR_TRUE; } + } - nsImapState imapState; - aImapUrl->GetRequiredImapState(&imapState); - - PRBool isSelectedStateUrl = imapState == - nsIImapUrl::nsImapSelectedState; - + nsImapState imapState; + aImapUrl->GetRequiredImapState(&imapState); + + PRBool isSelectedStateUrl = imapState == + nsIImapUrl::nsImapSelectedState; + nsCOMPtr msgUrl = do_QueryInterface(aImapUrl); - nsCOMPtr server; - rv = msgUrl->GetServer(getter_AddRefs(server)); - if (NS_SUCCEEDED(rv)) - { - // compare host/user between url and connection. - char * urlHostName = nsnull; - char * urlUserName = nsnull; - rv = server->GetHostName(&urlHostName); - if (NS_FAILED(rv)) return rv; - rv = server->GetUsername(&urlUserName); - if (NS_FAILED(rv)) return rv; - if ((!GetImapHostName() || - PL_strcasecmp(urlHostName, GetImapHostName()) == 0) && - (!GetImapUserName() || - PL_strcasecmp(urlUserName, GetImapUserName()) == 0)) - { - if (isSelectedStateUrl) - { - if (inSelectedState) - { - // *** jt - in selected state can only run url with - // matching foldername - char *srcFolderName = nsnull; - rv = aImapUrl->CreateServerSourceFolderPathString( - &srcFolderName); - if (NS_SUCCEEDED(rv) && srcFolderName) - { - PRBool isInbox = - PL_strcasecmp("Inbox", srcFolderName) == 0; - if (curUrlFolderName.Length() > 0) - { - PRBool matched = isInbox ? - PL_strcasecmp(curUrlFolderName.GetBuffer(), - srcFolderName) == 0 : - PL_strcmp(curUrlFolderName.GetBuffer(), - srcFolderName) == 0; - if (matched) - { - if (isBusy) - *hasToWait = PR_TRUE; - else - *aCanRunUrl = PR_TRUE; - } - } - } - PR_FREEIF(srcFolderName); - } - } - else // *** jt - an authenticated state url can be run in either - // authenticated or selected state - { - if (!isBusy) - *aCanRunUrl = PR_TRUE; - } - - PR_FREEIF(urlHostName); - PR_FREEIF(urlUserName); - } - } + nsCOMPtr server; + rv = msgUrl->GetServer(getter_AddRefs(server)); + if (NS_SUCCEEDED(rv)) + { + // compare host/user between url and connection. + char * urlHostName = nsnull; + char * urlUserName = nsnull; + rv = server->GetHostName(&urlHostName); + if (NS_FAILED(rv)) return rv; + rv = server->GetUsername(&urlUserName); + if (NS_FAILED(rv)) return rv; + if ((!GetImapHostName() || + PL_strcasecmp(urlHostName, GetImapHostName()) == 0) && + (!GetImapUserName() || + PL_strcasecmp(urlUserName, GetImapUserName()) == 0)) + { + if (isSelectedStateUrl) + { + if (inSelectedState) + { + // *** jt - in selected state can only run url with + // matching foldername + char *folderNameForProposedUrl = nsnull; + rv = aImapUrl->CreateServerSourceFolderPathString( + &folderNameForProposedUrl); + if (NS_SUCCEEDED(rv) && folderNameForProposedUrl) + { + PRBool isInbox = + PL_strcasecmp("Inbox", folderNameForProposedUrl) == 0; + if (curUrlFolderName.Length() > 0) + { + PRBool matched = isInbox ? + PL_strcasecmp(curUrlFolderName.GetBuffer(), + folderNameForProposedUrl) == 0 : + PL_strcmp(curUrlFolderName.GetBuffer(), + folderNameForProposedUrl) == 0; + if (matched) + { + if (isBusy) + *hasToWait = PR_TRUE; + else + *aCanRunUrl = PR_TRUE; + } + } + } +#ifdef DEBUG_bienvenu1 + printf("proposed url = %s folder for connection %s has To Wait = %s can run = %s\n", + folderNameForProposedUrl, curUrlFolderName.GetBuffer(), + (*hasToWait) ? "TRUE" : "FALSE", (*aCanRunUrl) ? "TRUE" : "FALSE"); +#endif + PR_FREEIF(folderNameForProposedUrl); + } + } + else // *** jt - an authenticated state url can be run in either + // authenticated or selected state + { + if (!isBusy) + *aCanRunUrl = PR_TRUE; + } + + PR_FREEIF(urlHostName); + PR_FREEIF(urlUserName); + } } + } NS_UNLOCK_INSTANCE(); return rv; } @@ -5182,6 +5224,12 @@ void nsImapProtocol::FindMailboxesIfNecessary() nsImapAction imapAction; nsresult rv = NS_OK; + // need to do this for every connection in order to see folders. +#ifdef DOING_PSEUDO_MAILBOXES + if (GetServerStateParser().ServerIsAOLServer()) + XAOL_Option("+READMBOX"); +#endif + rv = m_runningUrl->GetImapAction(&imapAction); rv = m_hostSessionList->GetHaveWeEverDiscoveredFoldersForHost(GetImapServerKey(), foundMailboxesAlready); if (NS_SUCCEEDED(rv) && !foundMailboxesAlready && @@ -5209,6 +5257,7 @@ void nsImapProtocol::FindMailboxesIfNecessary() void nsImapProtocol::DiscoverMailboxList() { PRBool usingSubscription = PR_FALSE; + SetMailboxDiscoveryStatus(eContinue); if (GetServerStateParser().ServerHasACLCapability()) m_hierarchyNameState = kListingForInfoAndDiscovery; @@ -5986,6 +6035,20 @@ void nsImapProtocol::Close() ParseIMAPandCheckForNewMail(); } +void nsImapProtocol::XAOL_Option(const char *option) +{ + IncrementCommandTagNumber(); + + nsCString command(GetServerCommandTag()); + command.Append(" XAOL-OPTION "); + command.Append(option); + command.Append(CRLF); + + nsresult rv = SendData(command.GetBuffer()); + if (NS_SUCCEEDED(rv)) + ParseIMAPandCheckForNewMail(); +} + void nsImapProtocol::Check() { //ProgressUpdateEvent("Checking mailbox..."); diff --git a/mailnews/imap/src/nsImapProtocol.h b/mailnews/imap/src/nsImapProtocol.h index bfffe8d3ac3..16af5e39983 100644 --- a/mailnews/imap/src/nsImapProtocol.h +++ b/mailnews/imap/src/nsImapProtocol.h @@ -250,6 +250,7 @@ public: void XServerInfo(); void Netscape(); void XMailboxInfo(const char *mailboxName); + void XAOL_Option(const char *option); void MailboxData(); void GetMyRightsForFolder(const char *mailboxName); void AutoSubscribeToMailboxIfNecessary(const char *mailboxName); @@ -287,8 +288,8 @@ public: const char* msgIdString); private: - // the following flag is used to determine when a url is currently being run. It is cleared on calls - // to ::StopBinding and it is set whenever we call Load on a url + // the following flag is used to determine when a url is currently being run. It is cleared when we + // finish processng a url and it is set whenever we call Load on a url PRBool m_urlInProgress; PRBool m_socketIsOpen; PRBool m_gotFEEventCompletion; diff --git a/mailnews/imap/src/nsImapServerResponseParser.cpp b/mailnews/imap/src/nsImapServerResponseParser.cpp index 280763705c5..785c0dd135b 100644 --- a/mailnews/imap/src/nsImapServerResponseParser.cpp +++ b/mailnews/imap/src/nsImapServerResponseParser.cpp @@ -655,6 +655,8 @@ void nsImapServerResponseParser::response_data() xserverinfo_data(); else if (!PL_strcasecmp(fNextToken, "XMAILBOXINFO")) xmailboxinfo_data(); + else if (!PL_strcasecmp(fNextToken, "XAOL-OPTION")) + skip_to_CRLF(); else SetSyntaxError(PR_TRUE); break; diff --git a/mailnews/imap/src/nsImapServerResponseParser.h b/mailnews/imap/src/nsImapServerResponseParser.h index e67e752a75f..54839066199 100644 --- a/mailnews/imap/src/nsImapServerResponseParser.h +++ b/mailnews/imap/src/nsImapServerResponseParser.h @@ -110,6 +110,7 @@ public: PRBool ServerHasNamespaceCapability() { return ((fCapabilityFlag & kNamespaceCapability) != 0); } PRBool ServerIsNetscape3xServer() { return fServerIsNetscape3xServer; } PRBool ServerHasServerInfo() {return ((fCapabilityFlag & kXServerInfoCapability) != 0); } + PRBool ServerIsAOLServer() {return ((fCapabilityFlag & kAOLImapCapability) != 0); } void ResetCapabilityFlag() ; const char *GetMailAccountUrl() { return fMailAccountUrl; } diff --git a/mailnews/imap/src/nsImapService.cpp b/mailnews/imap/src/nsImapService.cpp index ff4832cb10d..b2acf9de08a 100644 --- a/mailnews/imap/src/nsImapService.cpp +++ b/mailnews/imap/src/nsImapService.cpp @@ -181,14 +181,14 @@ nsImapService::SelectFolder(nsIEventQueue * aClientEventQueue, if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; - GetFolderName(aImapMailFolder, getter_Copies(folderName)); + nsXPIDLCString folderName; + GetFolderName(aImapMailFolder, getter_Copies(folderName)); urlSpec.Append("/select>"); urlSpec.Append(hierarchySeparator); - urlSpec.Append((const char *) folderName); - rv = mailNewsUrl->SetSpec((char *) urlSpec.GetBuffer()); - if (NS_SUCCEEDED(rv)) - rv = GetImapConnectionAndLoadUrl(aClientEventQueue, + urlSpec.Append((const char *) folderName); + rv = mailNewsUrl->SetSpec((char *) urlSpec.GetBuffer()); + if (NS_SUCCEEDED(rv)) + rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, nsnull, aURL); @@ -1618,7 +1618,7 @@ nsImapService::OnlineMessageCopy(nsIEventQueue* aClientEventQueue, GetFolderName(aDstFolder, getter_Copies(folderName)); urlSpec.Append((const char *) folderName); - rv = uri->SetSpec((char *) urlSpec.GetBuffer()); + rv = uri->SetSpec((char *) urlSpec.GetBuffer()); if (NS_SUCCEEDED(rv)) rv = GetImapConnectionAndLoadUrl(aClientEventQueue, imapUrl, nsnull, aURL);