fix fast delete breaking delete, r=mscott 32742

This commit is contained in:
bienvenu%netscape.com 2000-04-13 14:41:20 +00:00
Родитель ef6741cbff
Коммит 9e5e574372
9 изменённых файлов: 447 добавлений и 342 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 <nsIImapProtocol> aProtocol;
rv = CreateImapConnection(aClientEventQueue, aImapUrl, getter_AddRefs(aProtocol));
if (NS_FAILED(rv)) return rv;
nsresult rv = NS_OK;
nsCOMPtr <nsIImapProtocol> aProtocol;
rv = CreateImapConnection(aClientEventQueue, aImapUrl, getter_AddRefs(aProtocol));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIMsgMailNewsUrl> 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 <nsISupports> 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 <nsISupports> 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<nsISupports>
aSupport(getter_AddRefs(m_urlQueue->ElementAt(0)));
nsCOMPtr<nsIImapUrl>
aImapUrl(do_QueryInterface(aSupport, &rv));
if (aImapUrl)
{
nsCOMPtr<nsISupports>
aSupport(getter_AddRefs(m_urlQueue->ElementAt(0)));
nsCOMPtr<nsIImapUrl>
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 <nsIImapProtocol> protocolInstance ;
rv = CreateImapConnection(nsnull, aImapUrl,
getter_AddRefs(protocolInstance));
if (NS_SUCCEEDED(rv) && protocolInstance)
{
nsCOMPtr<nsIURI> 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 <nsIImapProtocol> protocolInstance ;
rv = CreateImapConnection(nsnull, aImapUrl,
getter_AddRefs(protocolInstance));
if (NS_SUCCEEDED(rv) && protocolInstance)
{
nsCOMPtr<nsIURI> 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<nsIImapProtocol> connection;
nsCOMPtr<nsIImapProtocol> freeConnection;
PRBool isBusy = PR_FALSE;
PRBool isInboxConnection = PR_FALSE;
nsCOMPtr<nsIImapProtocol> 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<nsISupports> aSupport;
nsCOMPtr<nsISupports> 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<nsIImapProtocol> 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);

Просмотреть файл

@ -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,

Просмотреть файл

@ -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<nsIMsgFolder> srcFolder;
srcFolder =
do_QueryInterface(m_copyState->m_srcSupport,
&rv);
nsCOMPtr<nsIMsgDatabase> 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<nsIMsgFolder> srcFolder;
srcFolder =
do_QueryInterface(m_copyState->m_srcSupport,
&rv);
nsCOMPtr<nsIMsgDatabase> srcDB;
if (NS_SUCCEEDED(rv))
rv = srcFolder->GetMsgDatabase(aWindow,
getter_AddRefs(srcDB));
if (NS_SUCCEEDED(rv) && srcDB)
{
nsCOMPtr<nsImapMoveCopyMsgTxn> 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<nsImapMoveCopyMsgTxn> 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();

Просмотреть файл

@ -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<nsIProxyObjectManager> proxyManager(do_GetService(kProxyObjectManagerCID));
nsCOMPtr<nsIProxyObjectManager> 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<nsIMsgMailNewsUrl> 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<nsIMsgMailNewsUrl> msgUrl = do_QueryInterface(aImapUrl);
nsCOMPtr<nsIMsgIncomingServer> 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<nsIMsgIncomingServer> 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...");

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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; }

Просмотреть файл

@ -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);