summaryrefslogtreecommitdiffstats
path: root/mailnews/local/src/nsLocalUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mailnews/local/src/nsLocalUtils.cpp')
-rw-r--r--mailnews/local/src/nsLocalUtils.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/mailnews/local/src/nsLocalUtils.cpp b/mailnews/local/src/nsLocalUtils.cpp
new file mode 100644
index 000000000..14a6a2f21
--- /dev/null
+++ b/mailnews/local/src/nsLocalUtils.cpp
@@ -0,0 +1,244 @@
+/* -*- 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"
+#include "nsLocalUtils.h"
+#include "nsIServiceManager.h"
+#include "prsystem.h"
+#include "nsCOMPtr.h"
+#include "prmem.h"
+// stuff for temporary root folder hack
+#include "nsIMsgAccountManager.h"
+#include "nsIMsgIncomingServer.h"
+#include "nsIPop3IncomingServer.h"
+#include "nsINoIncomingServer.h"
+#include "nsMsgBaseCID.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+
+#include "nsMsgUtils.h"
+#include "nsNetCID.h"
+
+// it would be really cool to:
+// - cache the last hostname->path match
+// - if no such server exists, behave like an old-style mailbox URL
+// (i.e. return the mail.directory preference or something)
+static nsresult
+nsGetMailboxServer(const char *uriStr, nsIMsgIncomingServer** aResult)
+{
+ nsresult rv = NS_OK;
+
+ nsCOMPtr<nsIURL> aUrl = do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = aUrl->SetSpec(nsDependentCString(uriStr));
+ if (NS_FAILED(rv)) return rv;
+
+ // retrieve the AccountManager
+ nsCOMPtr<nsIMsgAccountManager> accountManager =
+ do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ // find all local mail "no servers" matching the given hostname
+ nsCOMPtr<nsIMsgIncomingServer> none_server;
+ aUrl->SetScheme(NS_LITERAL_CSTRING("none"));
+ // No unescaping of username or hostname done here.
+ // The unescaping is done inside of FindServerByURI
+ rv = accountManager->FindServerByURI(aUrl, false,
+ getter_AddRefs(none_server));
+ if (NS_SUCCEEDED(rv)) {
+ NS_ADDREF(*aResult = none_server);
+ return rv;
+ }
+
+ // if that fails, look for the rss hosts matching the given hostname
+ nsCOMPtr<nsIMsgIncomingServer> rss_server;
+ aUrl->SetScheme(NS_LITERAL_CSTRING("rss"));
+ rv = accountManager->FindServerByURI(aUrl, false,
+ getter_AddRefs(rss_server));
+ if (NS_SUCCEEDED(rv))
+ {
+ NS_ADDREF(*aResult = rss_server);
+ return rv;
+ }
+#ifdef HAVE_MOVEMAIL
+ // find all movemail "servers" matching the given hostname
+ nsCOMPtr<nsIMsgIncomingServer> movemail_server;
+ aUrl->SetScheme(NS_LITERAL_CSTRING("movemail"));
+ rv = accountManager->FindServerByURI(aUrl, false,
+ getter_AddRefs(movemail_server));
+ if (NS_SUCCEEDED(rv)) {
+ NS_ADDREF(*aResult = movemail_server);
+ return rv;
+ }
+#endif /* HAVE_MOVEMAIL */
+
+ // if that fails, look for the pop hosts matching the given hostname
+ nsCOMPtr<nsIMsgIncomingServer> server;
+ if (NS_FAILED(rv))
+ {
+ aUrl->SetScheme(NS_LITERAL_CSTRING("pop3"));
+ rv = accountManager->FindServerByURI(aUrl, false,
+ getter_AddRefs(server));
+
+ // if we can't find a pop server, maybe it's a local message
+ // in an imap hierarchy. look for an imap server.
+ if (NS_FAILED(rv))
+ {
+ aUrl->SetScheme(NS_LITERAL_CSTRING("imap"));
+ rv = accountManager->FindServerByURI(aUrl, false,
+ getter_AddRefs(server));
+ }
+ }
+ if (NS_SUCCEEDED(rv))
+ {
+ NS_ADDREF(*aResult = server);
+ return rv;
+ }
+
+// if you fail after looking at all "pop3", "movemail" and "none" servers, you fail.
+return rv;
+}
+
+static nsresult
+nsLocalURI2Server(const char* uriStr,
+ nsIMsgIncomingServer ** aResult)
+{
+ nsresult rv;
+
+
+ nsCOMPtr<nsIMsgIncomingServer> server;
+ rv = nsGetMailboxServer(uriStr, getter_AddRefs(server));
+
+ NS_IF_ADDREF(*aResult = server);
+
+ return rv;
+}
+
+// given rootURI and rootURI##folder, return on-disk path of folder
+nsresult
+nsLocalURI2Path(const char* rootURI, const char* uriStr,
+ nsCString& pathResult)
+{
+ nsresult rv;
+
+ // verify that rootURI starts with "mailbox:/" or "mailbox-message:/"
+ if ((PL_strcmp(rootURI, kMailboxRootURI) != 0) &&
+ (PL_strcmp(rootURI, kMailboxMessageRootURI) != 0)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // verify that uristr starts with rooturi
+ nsAutoCString uri(uriStr);
+ if (uri.Find(rootURI) != 0)
+ return NS_ERROR_FAILURE;
+
+
+ nsCOMPtr<nsIMsgIncomingServer> server;
+ rv = nsLocalURI2Server(uriStr, getter_AddRefs(server));
+
+ if (NS_FAILED(rv))
+ return rv;
+
+ // now ask the server what it's root is
+ // and begin pathResult with the mailbox root
+ nsCOMPtr<nsIFile> localPath;
+ rv = server->GetLocalPath(getter_AddRefs(localPath));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString localNativePath;
+
+ localPath->GetNativePath(localNativePath);
+ nsEscapeNativePath(localNativePath);
+ pathResult = localNativePath.get();
+ const char *curPos = uriStr + PL_strlen(rootURI);
+ if (curPos) {
+ // advance past hostname
+ while ((*curPos)=='/') curPos++;
+ while (*curPos && (*curPos)!='/') curPos++;
+
+ nsAutoCString newPath("");
+
+ // Unescape folder name
+ if (curPos) {
+ nsCString unescapedStr;
+ MsgUnescapeString(nsDependentCString(curPos), 0, unescapedStr);
+ NS_MsgCreatePathStringFromFolderURI(unescapedStr.get(), newPath, NS_LITERAL_CSTRING("none"));
+ } else
+ NS_MsgCreatePathStringFromFolderURI(curPos, newPath, NS_LITERAL_CSTRING("none"));
+
+ pathResult.Append('/');
+ pathResult.Append(newPath);
+ }
+
+ return NS_OK;
+}
+
+/* parses LocalMessageURI
+ * mailbox-message://folder1/folder2#123?header=none or
+ * mailbox-message://folder1/folder2#1234&part=1.2
+ *
+ * puts folder URI in folderURI (mailbox://folder1/folder2)
+ * message key number in key
+ */
+nsresult nsParseLocalMessageURI(const char* uri,
+ nsCString& folderURI,
+ nsMsgKey *key)
+{
+ if(!key)
+ return NS_ERROR_NULL_POINTER;
+
+ nsAutoCString uriStr(uri);
+ int32_t keySeparator = uriStr.FindChar('#');
+ if(keySeparator != -1)
+ {
+ int32_t keyEndSeparator = MsgFindCharInSet(uriStr, "?&", keySeparator);
+ folderURI = StringHead(uriStr, keySeparator);
+ folderURI.Cut(7, 8); // cut out the -message part of mailbox-message:
+
+ nsAutoCString keyStr;
+ if (keyEndSeparator != -1)
+ keyStr = Substring(uriStr, keySeparator + 1,
+ keyEndSeparator - (keySeparator + 1));
+ else
+ keyStr = StringTail(uriStr, uriStr.Length() - (keySeparator + 1));
+
+ *key = msgKeyFromInt(ParseUint64Str(keyStr.get()));
+ return NS_OK;
+ }
+ return NS_ERROR_FAILURE;
+
+}
+
+nsresult nsBuildLocalMessageURI(const char *baseURI, nsMsgKey key, nsCString& uri)
+{
+ // need to convert mailbox://hostname/.. to mailbox-message://hostname/..
+ uri.Append(baseURI);
+ uri.Append('#');
+ uri.AppendInt(key);
+ return NS_OK;
+}
+
+nsresult nsCreateLocalBaseMessageURI(const nsACString& baseURI, nsCString &baseMessageURI)
+{
+ nsAutoCString tailURI(baseURI);
+
+ // chop off mailbox:/
+ if (tailURI.Find(kMailboxRootURI) == 0)
+ tailURI.Cut(0, PL_strlen(kMailboxRootURI));
+
+ baseMessageURI = kMailboxMessageRootURI;
+ baseMessageURI += tailURI;
+
+ return NS_OK;
+}
+
+void nsEscapeNativePath(nsCString& nativePath)
+{
+#if defined(XP_WIN)
+ nativePath.Insert('/', 0);
+ MsgReplaceChar(nativePath, '\\', '/');
+#endif
+}