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)
{
@ -264,6 +267,7 @@ nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue * aClientEventQu
// to run the url
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE, "shouldn't get an error loading url");
rv = aProtocol->LoadUrl(mailnewsurl, aConsumer);
}
else
@ -276,6 +280,7 @@ nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue * aClientEventQu
// 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);
@ -297,6 +302,9 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
PR_CEnterMonitor(this);
m_urlQueue->Count(&cnt);
// printf("loading next url, cnt = %ld\n", cnt);
if (cnt > 0)
{
nsCOMPtr<nsISupports>
@ -320,6 +328,7 @@ nsImapIncomingServer::LoadNextQueuedUrl(PRBool *aResult)
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);
@ -397,8 +406,8 @@ 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;
@ -430,24 +439,31 @@ nsImapIncomingServer::CreateImapConnection(nsIEventQueue *aEventQueue,
rv = m_connectionCache->Count(&cnt);
if (NS_FAILED(rv)) return rv;
for (PRUint32 i = 0; i < cnt && !canRunUrl && !hasToWait; i++)
// 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);
if (connection)
rv = connection->CanHandleUrl(aImapUrl, &canRunUrl, &hasToWait);
rv = connection->CanHandleUrl(aImapUrl, &canRunUrlImmediately, &canRunButBusy);
if (NS_FAILED(rv))
{
connection = null_nsCOMPtr();
continue;
}
if (!freeConnection && !canRunUrl && !hasToWait && connection)
// 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 (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))
@ -455,7 +471,7 @@ nsImapIncomingServer::CreateImapConnection(nsIEventQueue *aEventQueue,
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,16 +486,16 @@ 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)
else if (canRunButBusy)
{
// do nothing; return NS_OK; for queuing
}
@ -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,6 +3081,11 @@ 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)
{
@ -3142,6 +3154,8 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
m_transactionManager->Do(m_copyState->m_undoMsgTxn);
ClearCopyState(aExitCode);
}
else
NS_ASSERTION(PR_FALSE, "not clearing copy state");
}
break;
case nsIImapUrl::nsImapRenameFolder:
@ -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
@ -875,6 +882,7 @@ nsImapProtocol::ImapThreadMainLoop()
PR_ExitMonitor(m_urlReadyToRunMonitor);
if (err == PR_FAILURE && PR_PENDING_INTERRUPT_ERROR == PR_GetError())
{
printf("error waiting for monitor\n");
break;
}
@ -882,10 +890,10 @@ nsImapProtocol::ImapThreadMainLoop()
// m_sinkEventQueue->ProcessPendingEvents();
if (m_nextUrlReadyToRun && m_runningUrl)
ProcessCurrentURL();
{
m_nextUrlReadyToRun = PR_FALSE;
ProcessCurrentURL();
}
}
m_imapThreadIsRunning = PR_FALSE;
}
@ -1029,6 +1037,10 @@ PRBool nsImapProtocol::ProcessCurrentURL()
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,6 +1167,7 @@ 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)
{
@ -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;
@ -1386,9 +1420,9 @@ NS_IMETHODIMP nsImapProtocol::IsBusy(PRBool *aIsConnectionBusy,
}
else
{
if (m_runningUrl) // do we have a url? That means we're working on
// it...
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)
@ -1399,6 +1433,9 @@ NS_IMETHODIMP nsImapProtocol::IsBusy(PRBool *aIsConnectionBusy,
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)
@ -1475,20 +1512,20 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
{
// *** jt - in selected state can only run url with
// matching foldername
char *srcFolderName = nsnull;
char *folderNameForProposedUrl = nsnull;
rv = aImapUrl->CreateServerSourceFolderPathString(
&srcFolderName);
if (NS_SUCCEEDED(rv) && srcFolderName)
&folderNameForProposedUrl);
if (NS_SUCCEEDED(rv) && folderNameForProposedUrl)
{
PRBool isInbox =
PL_strcasecmp("Inbox", srcFolderName) == 0;
PL_strcasecmp("Inbox", folderNameForProposedUrl) == 0;
if (curUrlFolderName.Length() > 0)
{
PRBool matched = isInbox ?
PL_strcasecmp(curUrlFolderName.GetBuffer(),
srcFolderName) == 0 :
folderNameForProposedUrl) == 0 :
PL_strcmp(curUrlFolderName.GetBuffer(),
srcFolderName) == 0;
folderNameForProposedUrl) == 0;
if (matched)
{
if (isBusy)
@ -1498,7 +1535,12 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
}
}
}
PR_FREEIF(srcFolderName);
#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
@ -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; }