diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mailnews/local/src/nsMailboxService.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/mailnews/local/src/nsMailboxService.cpp')
-rw-r--r-- | comm/mailnews/local/src/nsMailboxService.cpp | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/comm/mailnews/local/src/nsMailboxService.cpp b/comm/mailnews/local/src/nsMailboxService.cpp new file mode 100644 index 0000000000..8a6a9766a8 --- /dev/null +++ b/comm/mailnews/local/src/nsMailboxService.cpp @@ -0,0 +1,559 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "msgCore.h" // precompiled header... +#include "nsCOMPtr.h" + +#include "nsMailboxService.h" +#include "nsMailboxUrl.h" +#include "nsIMsgMailNewsUrl.h" +#include "nsMailboxProtocol.h" +#include "nsIMsgDatabase.h" +#include "MailNewsTypes.h" +#include "nsTArray.h" +#include "nsLocalUtils.h" +#include "nsIDocShell.h" +#include "nsMsgUtils.h" +#include "nsPop3URL.h" +#include "nsNativeCharsetUtils.h" +#include "nsNetUtil.h" +#include "nsIWebNavigation.h" +#include "prprf.h" +#include "nsIMsgHdr.h" +#include "nsIFileURL.h" +#include "mozilla/RefPtr.h" +#include "mozilla/LoadInfo.h" +#include "nsDocShellLoadState.h" +#include "nsContentUtils.h" +#include "nsMsgFileHdr.h" + +nsMailboxService::nsMailboxService() {} + +nsMailboxService::~nsMailboxService() {} + +NS_IMPL_ISUPPORTS(nsMailboxService, nsIMailboxService, nsIMsgMessageService, + nsIProtocolHandler, nsIMsgMessageFetchPartService) + +nsresult nsMailboxService::ParseMailbox(nsIMsgWindow* aMsgWindow, + nsIFile* aMailboxPath, + nsIStreamListener* aMailboxParser, + nsIUrlListener* aUrlListener, + nsIURI** aURL) { + NS_ENSURE_ARG_POINTER(aMailboxPath); + + nsresult rv; + nsCOMPtr<nsIMailboxUrl> mailboxurl = + do_CreateInstance("@mozilla.org/messenger/mailboxurl;1", &rv); + if (NS_SUCCEEDED(rv) && mailboxurl) { + nsCOMPtr<nsIMsgMailNewsUrl> url = do_QueryInterface(mailboxurl); + // okay now generate the url string +#ifdef XP_WIN + nsString path = aMailboxPath->NativePath(); + nsCString mailboxPath; + NS_CopyUnicodeToNative(path, mailboxPath); +#else + nsCString mailboxPath = aMailboxPath->NativePath(); +#endif + nsAutoCString buf; + MsgEscapeURL(mailboxPath, + nsINetUtil::ESCAPE_URL_MINIMAL | nsINetUtil::ESCAPE_URL_FORCED, + buf); + nsEscapeNativePath(buf); + url->SetUpdatingFolder(true); + url->SetMsgWindow(aMsgWindow); + nsAutoCString uriSpec("mailbox://"); + uriSpec.Append(buf); + rv = url->SetSpecInternal(uriSpec); + NS_ENSURE_SUCCESS(rv, rv); + + mailboxurl->SetMailboxParser(aMailboxParser); + if (aUrlListener) url->RegisterListener(aUrlListener); + + rv = RunMailboxUrl(url, nullptr); + NS_ENSURE_SUCCESS(rv, rv); + + if (aURL) { + url.forget(aURL); + } + } + + return rv; +} + +nsresult nsMailboxService::CopyMessage(const nsACString& aSrcMailboxURI, + nsIStreamListener* aMailboxCopyHandler, + bool moveMessage, + nsIUrlListener* aUrlListener, + nsIMsgWindow* aMsgWindow) { + nsMailboxAction mailboxAction = nsIMailboxUrl::ActionMoveMessage; + nsCOMPtr<nsIURI> aURL; // unused... + if (!moveMessage) mailboxAction = nsIMailboxUrl::ActionCopyMessage; + return FetchMessage(aSrcMailboxURI, aMailboxCopyHandler, aMsgWindow, + aUrlListener, nullptr, mailboxAction, false, + getter_AddRefs(aURL)); +} + +nsresult nsMailboxService::CopyMessages( + const nsTArray<nsMsgKey>& aMsgKeys, nsIMsgFolder* srcFolder, + nsIStreamListener* aMailboxCopyHandler, bool moveMessage, + nsIUrlListener* aUrlListener, nsIMsgWindow* aMsgWindow, nsIURI** aURL) { + nsresult rv = NS_OK; + NS_ENSURE_ARG(srcFolder); + NS_ENSURE_TRUE(!aMsgKeys.IsEmpty(), NS_ERROR_INVALID_ARG); + nsCOMPtr<nsIMailboxUrl> mailboxurl; + + nsMailboxAction actionToUse = nsIMailboxUrl::ActionMoveMessage; + if (!moveMessage) actionToUse = nsIMailboxUrl::ActionCopyMessage; + + nsCOMPtr<nsIMsgDBHdr> msgHdr; + nsCOMPtr<nsIMsgDatabase> db; + srcFolder->GetMsgDatabase(getter_AddRefs(db)); + if (db) { + db->GetMsgHdrForKey(aMsgKeys[0], getter_AddRefs(msgHdr)); + if (msgHdr) { + nsCString uri; + srcFolder->GetUriForMsg(msgHdr, uri); + rv = PrepareMessageUrl(uri, aUrlListener, actionToUse, + getter_AddRefs(mailboxurl), aMsgWindow); + + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIURI> url = do_QueryInterface(mailboxurl); + nsCOMPtr<nsIMsgMailNewsUrl> msgUrl(do_QueryInterface(url)); + nsCOMPtr<nsIMailboxUrl> mailboxUrl(do_QueryInterface(url)); + msgUrl->SetMsgWindow(aMsgWindow); + + mailboxUrl->SetMoveCopyMsgKeys(aMsgKeys); + rv = RunMailboxUrl(url, aMailboxCopyHandler); + } + } + } + if (aURL && mailboxurl) CallQueryInterface(mailboxurl, aURL); + + return rv; +} + +nsresult nsMailboxService::FetchMessage( + const nsACString& aMessageURI, nsISupports* aDisplayConsumer, + nsIMsgWindow* aMsgWindow, nsIUrlListener* aUrlListener, + const char* aFileName, /* only used by open attachment... */ + nsMailboxAction mailboxAction, bool aAutodetectCharset, nsIURI** aURL) { + nsresult rv = NS_OK; + nsCOMPtr<nsIMailboxUrl> mailboxurl; + nsMailboxAction actionToUse = mailboxAction; + nsCOMPtr<nsIURI> url; + nsCOMPtr<nsIMsgMailNewsUrl> msgUrl; + nsAutoCString uriString(aMessageURI); + + if (StringBeginsWith(aMessageURI, "file:"_ns)) { + int64_t fileSize; + nsCOMPtr<nsIURI> fileUri; + rv = NS_NewURI(getter_AddRefs(fileUri), aMessageURI); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIFileURL> fileUrl = do_QueryInterface(fileUri, &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIFile> file; + rv = fileUrl->GetFile(getter_AddRefs(file)); + NS_ENSURE_SUCCESS(rv, rv); + file->GetFileSize(&fileSize); + uriString.Replace(0, 5, "mailbox:"_ns); + uriString.AppendLiteral("&number=0"); + rv = NS_NewURI(getter_AddRefs(url), uriString); + NS_ENSURE_SUCCESS(rv, rv); + + msgUrl = do_QueryInterface(url); + if (msgUrl) { + msgUrl->SetMsgWindow(aMsgWindow); + nsCOMPtr<nsIMailboxUrl> mailboxUrl = do_QueryInterface(msgUrl, &rv); + mailboxUrl->SetMessageSize((uint32_t)fileSize); + } + } else { + // this happens with forward inline of message/rfc822 attachment + // opened in a stand-alone msg window. + int32_t typeIndex = uriString.Find("&type=application/x-message-display"); + if (typeIndex != -1) { + uriString.Cut(typeIndex, + sizeof("&type=application/x-message-display") - 1); + rv = NS_NewURI(getter_AddRefs(url), uriString.get()); + mailboxurl = do_QueryInterface(url); + } else + rv = PrepareMessageUrl(aMessageURI, aUrlListener, actionToUse, + getter_AddRefs(mailboxurl), aMsgWindow); + + if (NS_SUCCEEDED(rv)) { + url = do_QueryInterface(mailboxurl); + msgUrl = do_QueryInterface(url); + msgUrl->SetMsgWindow(aMsgWindow); + if (aFileName) msgUrl->SetFileNameInternal(nsDependentCString(aFileName)); + } + } + + nsCOMPtr<nsIMsgI18NUrl> i18nurl(do_QueryInterface(msgUrl)); + if (i18nurl) i18nurl->SetAutodetectCharset(aAutodetectCharset); + + // instead of running the mailbox url like we used to, let's try to run the + // url in the docshell... + nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aDisplayConsumer, &rv)); + // if we were given a docShell, run the url in the docshell..otherwise just + // run it normally. + if (NS_SUCCEEDED(rv) && docShell && url) { + // DIRTY LITTLE HACK --> if we are opening an attachment we want the + // docshell to treat this load as if it were a user click event. Then the + // dispatching stuff will be much happier. + RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(url); + loadState->SetLoadFlags(mailboxAction == nsIMailboxUrl::ActionFetchPart + ? nsIWebNavigation::LOAD_FLAGS_IS_LINK + : nsIWebNavigation::LOAD_FLAGS_NONE); + if (mailboxAction == nsIMailboxUrl::ActionFetchPart) + loadState->SetLoadType(LOAD_LINK); + loadState->SetFirstParty(false); + loadState->SetTriggeringPrincipal(nsContentUtils::GetSystemPrincipal()); + rv = docShell->LoadURI(loadState, false); + } else + rv = RunMailboxUrl(url, aDisplayConsumer); + + if (aURL && mailboxurl) CallQueryInterface(mailboxurl, aURL); + + return rv; +} + +NS_IMETHODIMP nsMailboxService::FetchMimePart( + nsIURI* aURI, const nsACString& aMessageURI, nsISupports* aDisplayConsumer, + nsIMsgWindow* aMsgWindow, nsIUrlListener* aUrlListener, nsIURI** aURL) { + nsresult rv; + nsCOMPtr<nsIMsgMailNewsUrl> msgUrl(do_QueryInterface(aURI, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + msgUrl->SetMsgWindow(aMsgWindow); + + // set up the url listener + if (aUrlListener) msgUrl->RegisterListener(aUrlListener); + + return RunMailboxUrl(msgUrl, aDisplayConsumer); +} + +NS_IMETHODIMP nsMailboxService::LoadMessage(const nsACString& aMessageURI, + nsISupports* aDisplayConsumer, + nsIMsgWindow* aMsgWindow, + nsIUrlListener* aUrlListener, + bool aOverideCharset) { + nsCOMPtr<nsIURI> aURL; // unused... + return FetchMessage(aMessageURI, aDisplayConsumer, aMsgWindow, aUrlListener, + nullptr, nsIMailboxUrl::ActionFetchMessage, + aOverideCharset, getter_AddRefs(aURL)); +} + +NS_IMETHODIMP +nsMailboxService::StreamMessage(const nsACString& aMessageURI, + nsISupports* aConsumer, + nsIMsgWindow* aMsgWindow, + nsIUrlListener* aUrlListener, + bool /* aConvertData */, + const nsACString& aAdditionalHeader, + bool aLocalOnly, nsIURI** aURL) { + // The mailbox protocol object will look for "header=filter" or + // "header=attach" to decide if it wants to convert the data instead of + // using aConvertData. It turns out to be way too hard to pass aConvertData + // all the way over to the mailbox protocol object. + nsAutoCString aURIString(aMessageURI); + if (!aAdditionalHeader.IsEmpty()) { + aURIString.FindChar('?') == -1 ? aURIString += "?" : aURIString += "&"; + aURIString += "header="; + aURIString += aAdditionalHeader; + } + + return FetchMessage(aURIString, aConsumer, aMsgWindow, aUrlListener, nullptr, + nsIMailboxUrl::ActionFetchMessage, false, aURL); +} + +NS_IMETHODIMP nsMailboxService::StreamHeaders(const nsACString& aMessageURI, + nsIStreamListener* aConsumer, + nsIUrlListener* aUrlListener, + bool aLocalOnly, nsIURI** aURL) { + NS_ENSURE_ARG_POINTER(aConsumer); + nsAutoCString folderURI; + nsMsgKey msgKey; + nsCOMPtr<nsIMsgFolder> folder; + nsresult rv = + DecomposeMailboxURI(aMessageURI, getter_AddRefs(folder), &msgKey); + if (msgKey == nsMsgKey_None) return NS_MSG_MESSAGE_NOT_FOUND; + + nsCOMPtr<nsIMsgDatabase> db; + rv = folder->GetMsgDatabase(getter_AddRefs(db)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIMsgDBHdr> msgHdr; + rv = db->GetMsgHdrForKey(msgKey, getter_AddRefs(msgHdr)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr<nsIInputStream> inputStream; + rv = folder->GetLocalMsgStream(msgHdr, getter_AddRefs(inputStream)); + NS_ENSURE_SUCCESS(rv, rv); + return MsgStreamMsgHeaders(inputStream, aConsumer); +} + +NS_IMETHODIMP nsMailboxService::IsMsgInMemCache(nsIURI* aUrl, + nsIMsgFolder* aFolder, + bool* aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsMailboxService::SaveMessageToDisk(const nsACString& aMessageURI, + nsIFile* aFile, bool aAddDummyEnvelope, + nsIUrlListener* aUrlListener, nsIURI** aURL, + bool canonicalLineEnding, + nsIMsgWindow* aMsgWindow) { + nsresult rv = NS_OK; + nsCOMPtr<nsIMailboxUrl> mailboxurl; + + rv = PrepareMessageUrl(aMessageURI, aUrlListener, + nsIMailboxUrl::ActionSaveMessageToDisk, + getter_AddRefs(mailboxurl), aMsgWindow); + + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(mailboxurl); + if (msgUrl) { + msgUrl->SetMessageFile(aFile); + msgUrl->SetAddDummyEnvelope(aAddDummyEnvelope); + msgUrl->SetCanonicalLineEnding(canonicalLineEnding); + } + + nsCOMPtr<nsIURI> url = do_QueryInterface(mailboxurl); + rv = RunMailboxUrl(url); + } + + if (aURL && mailboxurl) CallQueryInterface(mailboxurl, aURL); + + return rv; +} + +NS_IMETHODIMP nsMailboxService::GetUrlForUri(const nsACString& aMessageURI, + nsIMsgWindow* aMsgWindow, + nsIURI** aURL) { + NS_ENSURE_ARG_POINTER(aURL); + if (StringBeginsWith(aMessageURI, "file:"_ns) || + PL_strstr(PromiseFlatCString(aMessageURI).get(), + "type=application/x-message-display") || + StringBeginsWith(aMessageURI, "mailbox:"_ns)) + return NS_NewURI(aURL, aMessageURI); + + nsresult rv = NS_OK; + nsCOMPtr<nsIMailboxUrl> mailboxurl; + rv = + PrepareMessageUrl(aMessageURI, nullptr, nsIMailboxUrl::ActionFetchMessage, + getter_AddRefs(mailboxurl), aMsgWindow); + if (NS_SUCCEEDED(rv) && mailboxurl) rv = CallQueryInterface(mailboxurl, aURL); + return rv; +} + +// Takes a mailbox url, this method creates a protocol instance and loads the +// url into the protocol instance. +nsresult nsMailboxService::RunMailboxUrl(nsIURI* aMailboxUrl, + nsISupports* aDisplayConsumer) { + // create a protocol instance to run the url.. + RefPtr<nsMailboxProtocol> protocol = new nsMailboxProtocol(aMailboxUrl); + // It implements nsIChannel, and all channels require loadInfo. + protocol->SetLoadInfo(new mozilla::net::LoadInfo( + nsContentUtils::GetSystemPrincipal(), nullptr, nullptr, + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, + nsIContentPolicy::TYPE_OTHER)); + nsresult rv = protocol->Initialize(aMailboxUrl); + NS_ENSURE_SUCCESS(rv, rv); + return protocol->LoadUrl(aMailboxUrl, aDisplayConsumer); +} + +// This function takes a message uri, converts it into a file path & msgKey +// pair. It then turns that into a mailbox url object. It also registers a url +// listener if appropriate. AND it can take in a mailbox action and set that +// field on the returned url as well. +nsresult nsMailboxService::PrepareMessageUrl( + const nsACString& aSrcMsgMailboxURI, nsIUrlListener* aUrlListener, + nsMailboxAction aMailboxAction, nsIMailboxUrl** aMailboxUrl, + nsIMsgWindow* msgWindow) { + nsresult rv = + CallCreateInstance("@mozilla.org/messenger/mailboxurl;1", aMailboxUrl); + if (NS_SUCCEEDED(rv) && aMailboxUrl && *aMailboxUrl) { + // okay now generate the url string + char* urlSpec; + nsAutoCString folderURI; + nsMsgKey msgKey; + nsCString folderPath; + const nsPromiseFlatCString& flat = PromiseFlatCString(aSrcMsgMailboxURI); + const char* part = PL_strstr(flat.get(), "part="); + const char* header = PL_strstr(flat.get(), "header="); + rv = nsParseLocalMessageURI(aSrcMsgMailboxURI, folderURI, &msgKey); + NS_ENSURE_SUCCESS(rv, rv); + rv = nsLocalURI2Path(kMailboxRootURI, folderURI.get(), folderPath); + + if (NS_SUCCEEDED(rv)) { + // set up the url spec and initialize the url with it. + nsAutoCString buf; + MsgEscapeURL( + folderPath, + nsINetUtil::ESCAPE_URL_DIRECTORY | nsINetUtil::ESCAPE_URL_FORCED, + buf); + if (part) + urlSpec = + PR_smprintf("mailbox://%s?number=%lu&%s", buf.get(), msgKey, part); + else if (header) + urlSpec = PR_smprintf("mailbox://%s?number=%lu&%s", buf.get(), msgKey, + header); + else + urlSpec = PR_smprintf("mailbox://%s?number=%lu", buf.get(), msgKey); + + nsCOMPtr<nsIMsgMailNewsUrl> url = do_QueryInterface(*aMailboxUrl); + rv = url->SetSpecInternal(nsDependentCString(urlSpec)); + NS_ENSURE_SUCCESS(rv, rv); + + PR_smprintf_free(urlSpec); + + (*aMailboxUrl)->SetMailboxAction(aMailboxAction); + + // set up the url listener + if (aUrlListener) rv = url->RegisterListener(aUrlListener); + + url->SetMsgWindow(msgWindow); + nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(url); + if (msgUrl) { + msgUrl->SetOriginalSpec(aSrcMsgMailboxURI); + msgUrl->SetUri(aSrcMsgMailboxURI); + } + + } // if we got a url + } // if we got a url + + return rv; +} + +NS_IMETHODIMP nsMailboxService::GetScheme(nsACString& aScheme) { + aScheme = "mailbox"; + return NS_OK; +} + +NS_IMETHODIMP nsMailboxService::AllowPort(int32_t port, const char* scheme, + bool* _retval) { + NS_ENSURE_ARG_POINTER(_retval); + // don't override anything. + *_retval = false; + return NS_OK; +} + +nsresult nsMailboxService::NewURI(const nsACString& aSpec, + const char* aOriginCharset, nsIURI* aBaseURI, + nsIURI** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = 0; + nsresult rv; + nsCOMPtr<nsIMsgMailNewsUrl> aMsgUri = + do_CreateInstance("@mozilla.org/messenger/mailboxurl;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + // SetSpecInternal must not fail, or else the URL won't have a base URL and + // we'll crash later. + if (aBaseURI) { + nsAutoCString newSpec; + rv = aBaseURI->Resolve(aSpec, newSpec); + NS_ENSURE_SUCCESS(rv, rv); + rv = aMsgUri->SetSpecInternal(newSpec); + NS_ENSURE_SUCCESS(rv, rv); + } else { + rv = aMsgUri->SetSpecInternal(aSpec); + NS_ENSURE_SUCCESS(rv, rv); + } + aMsgUri.forget(_retval); + + return rv; +} + +NS_IMETHODIMP nsMailboxService::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo, + nsIChannel** _retval) { + NS_ENSURE_ARG_POINTER(aURI); + NS_ENSURE_ARG_POINTER(_retval); + MOZ_ASSERT(aLoadInfo); + nsresult rv = NS_OK; + nsAutoCString spec; + rv = aURI->GetSpec(spec); + NS_ENSURE_SUCCESS(rv, rv); + + if (spec.Find("?uidl=") >= 0 || spec.Find("&uidl=") >= 0) { + nsCOMPtr<nsIProtocolHandler> handler = + do_GetService("@mozilla.org/network/protocol;1?name=pop", &rv); + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIURI> pop3Uri; + + rv = nsPop3URL::NewURI(spec, aURI, getter_AddRefs(pop3Uri)); + NS_ENSURE_SUCCESS(rv, rv); + return handler->NewChannel(pop3Uri, aLoadInfo, _retval); + } + } + + RefPtr<nsMailboxProtocol> protocol = new nsMailboxProtocol(aURI); + if (!protocol) { + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = protocol->Initialize(aURI); + NS_ENSURE_SUCCESS(rv, rv); + + rv = protocol->SetLoadInfo(aLoadInfo); + NS_ENSURE_SUCCESS(rv, rv); + + // Add the attachment disposition. This forces docShell to open the + // attachment instead of displaying it. Content types we have special + // handlers for are white-listed. This white list also exists in + // nsImapService::NewChannel and nsNntpService::NewChannel, so if you're + // changing this, update those too. + if (spec.Find("part=") >= 0 && spec.Find("type=message/rfc822") < 0 && + spec.Find("type=application/x-message-display") < 0 && + spec.Find("type=application/pdf") < 0) { + rv = protocol->SetContentDisposition(nsIChannel::DISPOSITION_ATTACHMENT); + NS_ENSURE_SUCCESS(rv, rv); + } + + protocol.forget(_retval); + return NS_OK; +} + +NS_IMETHODIMP nsMailboxService::Search(nsIMsgSearchSession* aSearchSession, + nsIMsgWindow* aMsgWindow, + nsIMsgFolder* aMsgFolder, + const nsACString& aMessageUri) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult nsMailboxService::DecomposeMailboxURI(const nsACString& aMessageURI, + nsIMsgFolder** aFolder, + nsMsgKey* aMsgKey) { + NS_ENSURE_ARG_POINTER(aFolder); + NS_ENSURE_ARG_POINTER(aMsgKey); + + nsresult rv = NS_OK; + nsAutoCString folderURI; + rv = nsParseLocalMessageURI(aMessageURI, folderURI, aMsgKey); + NS_ENSURE_SUCCESS(rv, rv); + + return GetOrCreateFolder(folderURI, aFolder); +} + +NS_IMETHODIMP +nsMailboxService::MessageURIToMsgHdr(const nsACString& uri, + nsIMsgDBHdr** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + + if (StringBeginsWith(uri, "file:"_ns)) { + nsCOMPtr<nsIMsgDBHdr> msgHdr = new nsMsgFileHdr(uri); + msgHdr.forget(_retval); + return NS_OK; + } + + nsresult rv = NS_OK; + + nsCOMPtr<nsIMsgFolder> folder; + nsMsgKey msgKey; + + rv = DecomposeMailboxURI(uri, getter_AddRefs(folder), &msgKey); + NS_ENSURE_SUCCESS(rv, rv); + + rv = folder->GetMessageHeader(msgKey, _retval); + NS_ENSURE_SUCCESS(rv, rv); + return NS_OK; +} |