From aed872e58331a91eb564938152d048aa2f5fb062 Mon Sep 17 00:00:00 2001 From: "jefft%netscape.com" Date: Fri, 28 Jan 2000 15:38:16 +0000 Subject: [PATCH] partial fix for bug 20366 - imap rename problem, bug 24749 - need to make sure namespace, acl works on cyrus server;staged checkin 1; r=bienvenu git-svn-id: svn://10.0.0.236/trunk@59077 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/mailnews/imap/src/nsIMAPNamespace.cpp | 3 + mozilla/mailnews/imap/src/nsImapCore.h | 1 + .../mailnews/imap/src/nsImapMailFolder.cpp | 110 +++++++++++++++--- mozilla/mailnews/imap/src/nsImapMailFolder.h | 2 + mozilla/mailnews/imap/src/nsImapProtocol.cpp | 61 ++++++++-- mozilla/mailnews/imap/src/nsImapProtocol.h | 3 + 6 files changed, 155 insertions(+), 25 deletions(-) diff --git a/mozilla/mailnews/imap/src/nsIMAPNamespace.cpp b/mozilla/mailnews/imap/src/nsIMAPNamespace.cpp index d8bf311d820..3bd5a55f51b 100644 --- a/mozilla/mailnews/imap/src/nsIMAPNamespace.cpp +++ b/mozilla/mailnews/imap/src/nsIMAPNamespace.cpp @@ -60,6 +60,9 @@ int nsIMAPNamespace::MailboxMatchesNamespace(const char *boxname) if (!boxname) return -1; // If the namespace is part of the boxname + if (PL_strlen(m_prefix) == 0) + return 0; + if (PL_strstr(boxname, m_prefix) == boxname) return PL_strlen(m_prefix); diff --git a/mozilla/mailnews/imap/src/nsImapCore.h b/mozilla/mailnews/imap/src/nsImapCore.h index 7490f0e4f6d..d3ef3c94997 100644 --- a/mozilla/mailnews/imap/src/nsImapCore.h +++ b/mozilla/mailnews/imap/src/nsImapCore.h @@ -47,6 +47,7 @@ typedef PRUint16 imapMessageFlagsType; #define kPublicMailbox 0x80 /* this mailbox is in the public namespace */ #define kOtherUsersMailbox 0x100 /* this mailbox is in the other users' namespace */ #define kNameSpace 0x200 /* this mailbox IS a namespace */ +#define kImapSent 0x400 /* Navigator flag; Sent folder*/ /* flags for individual messages */ /* currently the ui only offers \Seen and \Flagged */ diff --git a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp index cfe00cbdd52..e66444a7e96 100644 --- a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp @@ -668,10 +668,36 @@ NS_IMETHODIMP nsImapMailFolder::GetHierarchyDelimiter(PRUnichar *aHierarchyDelim NS_IMETHODIMP nsImapMailFolder::SetBoxFlags(PRInt32 aBoxFlags) { m_boxFlags = aBoxFlags; + mFlags |= MSG_FOLDER_FLAG_IMAPBOX; + if (m_boxFlags & kNoinferiors) mFlags |= MSG_FOLDER_FLAG_IMAP_NOINFERIORS; else mFlags &= ~MSG_FOLDER_FLAG_IMAP_NOINFERIORS; + if (m_boxFlags & kImapTrash) + mFlags |= MSG_FOLDER_FLAG_TRASH; + else + mFlags &= ~MSG_FOLDER_FLAG_TRASH; + if (m_boxFlags & kImapSent) + mFlags |= MSG_FOLDER_FLAG_SENTMAIL; + else + mFlags &= ~MSG_FOLDER_FLAG_SENTMAIL; + if (m_boxFlags & kNoselect) + mFlags |= MSG_FOLDER_FLAG_IMAP_NOSELECT; + else + mFlags &= ~MSG_FOLDER_FLAG_IMAP_NOSELECT; + if (m_boxFlags & kPublicMailbox) + mFlags |= MSG_FOLDER_FLAG_IMAP_PUBLIC; + else + mFlags &= ~MSG_FOLDER_FLAG_IMAP_PUBLIC; + if (m_boxFlags & kOtherUsersMailbox) + mFlags |= MSG_FOLDER_FLAG_IMAP_OTHER_USER; + else + mFlags &= ~MSG_FOLDER_FLAG_IMAP_OTHER_USER; + if (m_boxFlags & kPersonalMailbox) + mFlags |= MSG_FOLDER_FLAG_IMAP_PERSONAL; + else + mFlags &= ~MSG_FOLDER_FLAG_IMAP_PERSONAL; return NS_OK; } @@ -794,6 +820,47 @@ NS_IMETHODIMP nsImapMailFolder::Delete () NS_IMETHODIMP nsImapMailFolder::Rename (const char *newName) { nsresult rv = NS_ERROR_FAILURE; + + rv = RenameLocal(newName); + + NS_WITH_SERVICE (nsIImapService, imapService, kCImapService, &rv); + if (NS_SUCCEEDED(rv)) + rv = imapService->RenameLeaf(m_eventQueue, this, newName, this, + nsnull); + return rv; +} + +NS_IMETHODIMP nsImapMailFolder::ForceDBClosed() +{ + PRUint32 cnt = 0, i; + if (mSubFolders) + { + nsCOMPtr aSupport; + nsCOMPtr child; + mSubFolders->Count(&cnt); + if (cnt > 0) + for (i = 0; i < cnt; i++) + { + aSupport = getter_AddRefs(mSubFolders->ElementAt(i)); + child = do_QueryInterface(aSupport); + if (child) + child->ForceDBClosed(); + } + } + if (mDatabase) + { + mDatabase->ForceClosed(); + mDatabase = null_nsCOMPtr(); + } + return NS_OK; +} + +nsresult nsImapMailFolder::RenameLocal(const char *newName) +{ + m_msgParser = null_nsCOMPtr(); + ForceDBClosed(); + + nsresult rv = NS_OK; nsCOMPtr oldPathSpec; rv = GetPath(getter_AddRefs(oldPathSpec)); if (NS_FAILED(rv)) return rv; @@ -801,37 +868,36 @@ NS_IMETHODIMP nsImapMailFolder::Rename (const char *newName) rv = GetParent(getter_AddRefs(parent)); if (NS_FAILED(rv)) return rv; nsCOMPtr parentFolder = do_QueryInterface(parent); - Shutdown(PR_TRUE); PRUint32 cnt = 0; nsFileSpec dirSpec; if (mSubFolders) mSubFolders->Count(&cnt); if (cnt > 0) - rv = CreateDirectoryForFolder(dirSpec); - - if (parentFolder) { - SetParent(nsnull); - parentFolder->PropagateDelete(this, PR_FALSE); + oldPathSpec->GetFileSpec(&dirSpec); + rv = CreateDirectoryForFolder(dirSpec); } nsFileSpec fileSpec; oldPathSpec->GetFileSpec(&fileSpec); nsLocalFolderSummarySpec oldSummarySpec(fileSpec); nsCAutoString newNameStr = newName; newNameStr += ".msf"; - oldSummarySpec.Rename(newNameStr.GetBuffer()); - if (NS_SUCCEEDED(rv) && cnt> 0) - { - newNameStr = newName; - newNameStr += ".sbd"; - dirSpec.Rename(newNameStr.GetBuffer()); - } - - NS_WITH_SERVICE (nsIImapService, imapService, kCImapService, &rv); + rv = oldSummarySpec.Rename(newNameStr.GetBuffer()); if (NS_SUCCEEDED(rv)) - rv = imapService->RenameLeaf(m_eventQueue, this, newName, this, - nsnull); + { + if (parentFolder) + { + SetParent(nsnull); + parentFolder->PropagateDelete(this, PR_FALSE); + } + if (cnt > 0) + { + newNameStr = newName; + newNameStr += ".sbd"; + dirSpec.Rename(newNameStr.GetBuffer()); + } + } return rv; } @@ -2873,6 +2939,15 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode) } } break; + case nsIImapUrl::nsImapRenameFolder: + if (NS_FAILED(aExitCode)) + { + char *oldName = nsnull; + imapUrl->CreateServerDestinationFolderPathString(&oldName); + RenameLocal(oldName); + nsCRT::free(oldName); + } + break; default: break; } @@ -3677,3 +3752,4 @@ NS_IMETHODIMP nsImapMailFolder::MatchName(nsString *name, PRBool *matches) *matches = mName.Equals(*name, isInbox); return NS_OK; } + diff --git a/mozilla/mailnews/imap/src/nsImapMailFolder.h b/mozilla/mailnews/imap/src/nsImapMailFolder.h index fbb7d4d0068..f8994ba56fb 100644 --- a/mozilla/mailnews/imap/src/nsImapMailFolder.h +++ b/mozilla/mailnews/imap/src/nsImapMailFolder.h @@ -118,6 +118,7 @@ public: NS_IMETHOD CreateSubfolder(const char *folderName); NS_IMETHOD AddSubfolder(nsAutoString *name, nsIMsgFolder **child); + NS_IMETHOD ForceDBClosed(); NS_IMETHOD Compact(); NS_IMETHOD EmptyTrash(); NS_IMETHOD Delete (); @@ -278,6 +279,7 @@ protected: PRBool InTrash(nsIMsgFolder* folder); nsresult GetServerKey(char **serverKey); + nsresult RenameLocal(const char *newName); nsresult AddDirectorySeparator(nsFileSpec &path); nsresult CreateDirectoryForFolder(nsFileSpec &path); nsresult CreateSubFolders(nsFileSpec &path); diff --git a/mozilla/mailnews/imap/src/nsImapProtocol.cpp b/mozilla/mailnews/imap/src/nsImapProtocol.cpp index a19a2018b85..0fd676fa511 100644 --- a/mozilla/mailnews/imap/src/nsImapProtocol.cpp +++ b/mozilla/mailnews/imap/src/nsImapProtocol.cpp @@ -71,6 +71,7 @@ PRLogModuleInfo *IMAP; #define FOUR_K ((PRUint32)4096) const char *kImapTrashFolderName = "Trash"; // **** needs to be localized **** +const char *kImapSentFolderName = "Sent"; // **** needs to be localized **** static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID); @@ -241,6 +242,8 @@ nsImapProtocol::nsImapProtocol() : m_imapThreadIsRunning = PR_FALSE; m_currentServerCommandTagNumber = 0; m_active = PR_FALSE; + m_folderNeedsSubscribing = PR_FALSE; + m_folderNeedsACLRefreshed = PR_FALSE; m_threadShouldDie = PR_FALSE; m_pseudoInterrupted = PR_FALSE; m_nextUrlReadyToRun = PR_FALSE; @@ -1110,8 +1113,10 @@ PRBool nsImapProtocol::ProcessCurrentURL() if (mailnewsurl && m_imapMiscellaneousSink) { + rv = GetServerStateParser().LastCommandSuccessful() ? NS_OK : + NS_ERROR_FAILURE; m_imapMiscellaneousSink->SetUrlState(this, mailnewsurl, PR_FALSE, - NS_OK); // we are done with this + rv); // we are done with this // url. WaitForFEEventCompletion(); } @@ -1576,7 +1581,7 @@ void nsImapProtocol::ProcessSelectedStateURL() if (selectIssued) { -// RefreshACLForFolderIfNecessary(mailboxName); + RefreshACLForFolderIfNecessary(mailboxName); } PRBool uidValidityOk = PR_TRUE; @@ -2016,7 +2021,7 @@ void nsImapProtocol::ProcessSelectedStateURL() void nsImapProtocol::AutoSubscribeToMailboxIfNecessary(const char *mailboxName) { #ifdef HAVE_PORT - if (fFolderNeedsSubscribing) // we don't know about this folder - we need to subscribe to it / list it. + if (m_folderNeedsSubscribing) // we don't know about this folder - we need to subscribe to it / list it. { fHierarchyNameState = kListingForInfoOnly; List(mailboxName, PR_FALSE); @@ -2052,7 +2057,7 @@ void nsImapProtocol::AutoSubscribeToMailboxIfNecessary(const char *mailboxName) // We should now be subscribed to it, and have it in our folder lists // and panes. Even if something failed, we don't want to try this again. - fFolderNeedsSubscribing = PR_FALSE; + m_folderNeedsSubscribing = PR_FALSE; } #endif @@ -3758,7 +3763,7 @@ nsImapProtocol::DiscoverMailboxSpec(nsImapMailboxSpec * adoptedBoxSpec) PRUnichar slash = '/'; canonicalSubDir = nsPrefix; if (canonicalSubDir.Length() && canonicalSubDir.Last() == slash) - canonicalSubDir.SetCharAt((PRUnichar)0, canonicalSubDir.Length()); + canonicalSubDir.SetLength((PRUint32) canonicalSubDir.Length()-1); } switch (m_hierarchyNameState) @@ -3892,7 +3897,7 @@ nsImapProtocol::DiscoverMailboxSpec(nsImapMailboxSpec * adoptedBoxSpec) NS_ASSERTION(m_deletableChildren, "Oops .. null m_deletableChildren\n"); m_deletableChildren->AppendElement((void*) - adoptedBoxSpec->allocatedPathName); + nsCRT::strdup(adoptedBoxSpec->allocatedPathName)); PR_FREEIF(adoptedBoxSpec->hostName); NS_IF_RELEASE( adoptedBoxSpec); } @@ -4686,6 +4691,16 @@ void nsImapProtocol::OnUnsubscribe(const char * sourceMailbox) GetServerStateParser().SetReportingErrors(lastReportingErrors); } +void nsImapProtocol::RefreshACLForFolderIfNecessary(const char *mailboxName) +{ + if (m_folderNeedsACLRefreshed && + GetServerStateParser().ServerHasACLCapability()) + { + OnRefreshACLForFolder(mailboxName); + m_folderNeedsACLRefreshed = PR_FALSE; + } +} + void nsImapProtocol::OnRefreshACLForFolder(const char *mailboxName) { IncrementCommandTagNumber(); @@ -4705,8 +4720,37 @@ void nsImapProtocol::OnRefreshACLForFolder(const char *mailboxName) void nsImapProtocol::OnRefreshAllACLs() { - GetServerStateParser().SetReportingErrors(PR_TRUE); - // mscott - haven't ported this yet + m_hierarchyNameState = kListingForInfoOnly; + nsIMAPMailboxInfo *mb = NULL; + + // This will fill in the list + List("*", PR_TRUE); + + PRInt32 total = m_listedMailboxList.Count(), count = 0; + GetServerStateParser().SetReportingErrors(PR_FALSE); + do + { + mb = (nsIMAPMailboxInfo *) m_listedMailboxList.ElementAt(0); + m_listedMailboxList.RemoveElementAt(0); + if (mb) + { + char *onlineName = nsnull; + m_runningUrl->AllocateServerPath(mb->GetMailboxName(), + mb->GetDelimiter(), &onlineName); + if (onlineName) + { + OnRefreshACLForFolder(onlineName); + nsCRT::free(onlineName); + } + PercentProgressUpdateEvent(NULL, (count*100)/total); + delete mb; + count++; + } + } while (mb); + + PercentProgressUpdateEvent(NULL, 100); + GetServerStateParser().SetReportingErrors(PR_TRUE); + m_hierarchyNameState = kNoOperationInProgress; } // any state commands @@ -4993,6 +5037,7 @@ PRBool nsImapProtocol::RenameHierarchyByHand(const char *oldParentMailboxName, { nsCString pattern = oldParentMailboxName; pattern += ns->GetDelimiter(); + pattern += "*"; PRBool isUsingSubscription = PR_FALSE; m_hostSessionList->GetHostIsUsingSubscription(GetImapServerKey(), isUsingSubscription); diff --git a/mozilla/mailnews/imap/src/nsImapProtocol.h b/mozilla/mailnews/imap/src/nsImapProtocol.h index 96252eb4e92..9c44ec7ee7f 100644 --- a/mozilla/mailnews/imap/src/nsImapProtocol.h +++ b/mozilla/mailnews/imap/src/nsImapProtocol.h @@ -410,6 +410,8 @@ private: // state ported over from 4.5 PRBool m_pseudoInterrupted; PRBool m_active; + PRBool m_folderNeedsSubscribing; + PRBool m_folderNeedsACLRefreshed; PRBool m_threadShouldDie; nsImapFlagAndUidState *m_flagState; nsMsgBiffState m_currentBiffState; @@ -441,6 +443,7 @@ private: void OnCreateFolder(const char * aSourceMailbox); void OnSubscribe(const char * aSourceMailbox); void OnUnsubscribe(const char * aSourceMailbox); + void RefreshACLForFolderIfNecessary(const char * mailboxName); void OnRefreshACLForFolder(const char * aSourceMailbox); void OnRefreshAllACLs(); void OnListFolder(const char * aSourceMailbox, PRBool aBool);