From 7af796e20ca96337fd9007c5bb3906de33f2c904 Mon Sep 17 00:00:00 2001 From: "alecf%netscape.com" Date: Tue, 22 Jun 1999 03:03:48 +0000 Subject: [PATCH] add userid@ to all mail/news URIs and add parsing code to support this this change allows servers to be unique by {userid, hostname, type} combination and allows nsIMsgAccountManager::FindServer() to search for servers this way. --- mailnews/base/public/nsIMsgAccountManager.idl | 3 +- mailnews/base/public/nsIMsgFolder.idl | 4 +- mailnews/base/src/nsMsgAccountManager.cpp | 55 +++-- mailnews/base/util/nsMsgFolder.cpp | 31 ++- mailnews/base/util/nsMsgFolder.h | 10 +- mailnews/imap/src/nsImapIncomingServer.cpp | 18 +- mailnews/imap/src/nsImapMailFolder.cpp | 49 ++-- mailnews/imap/src/nsImapMailFolder.h | 6 +- mailnews/imap/src/nsImapService.cpp | 16 +- mailnews/imap/src/nsImapUrl.cpp | 28 ++- mailnews/imap/src/nsImapUtils.cpp | 71 +++--- mailnews/imap/src/nsImapUtils.h | 3 - mailnews/local/src/nsLocalMailFolder.cpp | 9 +- mailnews/local/src/nsLocalMailFolder.h | 6 +- mailnews/local/src/nsLocalUtils.cpp | 222 +++++++++++------- mailnews/local/src/nsLocalUtils.h | 5 +- mailnews/local/src/nsPop3IncomingServer.cpp | 15 +- mailnews/news/src/nsNewsFolder.cpp | 12 +- mailnews/news/src/nsNewsFolder.h | 8 +- mailnews/news/src/nsNewsUtils.cpp | 82 +++---- mailnews/news/src/nsNewsUtils.h | 3 - mailnews/news/src/nsNntpIncomingServer.cpp | 16 +- 22 files changed, 386 insertions(+), 286 deletions(-) diff --git a/mailnews/base/public/nsIMsgAccountManager.idl b/mailnews/base/public/nsIMsgAccountManager.idl index 1c959952182..e7643c01244 100644 --- a/mailnews/base/public/nsIMsgAccountManager.idl +++ b/mailnews/base/public/nsIMsgAccountManager.idl @@ -58,7 +58,8 @@ interface nsIMsgAccountManager : nsISupports { readonly attribute nsISupportsArray allIdentities; readonly attribute nsISupportsArray allServers; - nsISupportsArray FindServersByHostname(in string hostname, in nsIIDRef iid); + nsIMsgIncomingServer + FindServer(in string userName, in string hostname, in string type); nsISupportsArray GetIdentitiesForServer(in nsIMsgIncomingServer server); nsISupportsArray GetServersForIdentity(in nsIMsgIdentity identity); diff --git a/mailnews/base/public/nsIMsgFolder.idl b/mailnews/base/public/nsIMsgFolder.idl index 0c8b96f7f0a..a979d6a9380 100644 --- a/mailnews/base/public/nsIMsgFolder.idl +++ b/mailnews/base/public/nsIMsgFolder.idl @@ -102,8 +102,8 @@ interface nsIMsgFolder : nsIFolder { void RememberPassword(in string password); string GetRememberedPassword(); boolean UserNeedsToAuthenticateForFolder(in boolean displayOnly); - string GetUsersName(); - string GetHostName(); + string GetUsername(); + string GetHostname(); void SetFlag(in unsigned long flag); diff --git a/mailnews/base/src/nsMsgAccountManager.cpp b/mailnews/base/src/nsMsgAccountManager.cpp index b66c145e9fd..79b0af5ebac 100644 --- a/mailnews/base/src/nsMsgAccountManager.cpp +++ b/mailnews/base/src/nsMsgAccountManager.cpp @@ -55,8 +55,9 @@ typedef struct _findAccountEntry { // put them in "servers" typedef struct _findServerEntry { const char *hostname; - const nsIID *iid; - nsISupportsArray *servers; + const char *username; + const char *type; + nsIMsgIncomingServer *server; } findServerEntry; @@ -112,9 +113,10 @@ public: NS_IMETHOD LoadAccounts(); - NS_IMETHOD FindServersByHostname(const char* hostname, - const nsIID& iid, - nsISupportsArray* *serverArray); + NS_IMETHOD FindServer(const char* username, + const char* hostname, + const char *type, + nsIMsgIncomingServer* *aResult); NS_IMETHOD GetIdentitiesForServer(nsIMsgIncomingServer *server, nsISupportsArray **_retval); @@ -763,9 +765,10 @@ nsMsgAccountManager::upgradePrefs() } NS_IMETHODIMP -nsMsgAccountManager::FindServersByHostname(const char* hostname, - const nsIID& iid, - nsISupportsArray* *matchingServers) +nsMsgAccountManager::FindServer(const char* username, + const char* hostname, + const char* type, + nsIMsgIncomingServer** aResult) { nsresult rv; nsCOMPtr servers; @@ -773,17 +776,18 @@ nsMsgAccountManager::FindServersByHostname(const char* hostname, rv = GetAllServers(getter_AddRefs(servers)); if (NS_FAILED(rv)) return rv; - rv = NS_NewISupportsArray(matchingServers); - if (NS_FAILED(rv)) return rv; - findServerEntry serverInfo; serverInfo.hostname = hostname; - serverInfo.iid = &iid; - serverInfo.servers = *matchingServers; + // username might be blank, pass "" instead + serverInfo.username = username ? username : ""; + serverInfo.type = type; + serverInfo.server = *aResult = nsnull; servers->EnumerateForwards(findServerByName, (void *)&serverInfo); - // as long as we have an nsISupportsArray, we are successful + if (!serverInfo.server) return NS_ERROR_UNEXPECTED; + *aResult = serverInfo.server; + return NS_OK; } @@ -798,16 +802,27 @@ nsMsgAccountManager::findServerByName(nsISupports *aElement, void *data) findServerEntry *entry = (findServerEntry*) data; + nsresult rv; + nsXPIDLCString thisHostname; - nsresult rv = server->GetHostName(getter_Copies(thisHostname)); + rv = server->GetHostName(getter_Copies(thisHostname)); if (NS_FAILED(rv)) return PR_TRUE; - // do a QI to see if we support this interface, but be sure to release it! - nsISupports* dummy; + char *username=nsnull; + rv = server->GetUsername(&username); + if (NS_FAILED(rv)) return PR_TRUE; + if (!username) username=PL_strdup(""); + + nsXPIDLCString thisType; + rv = server->GetType(getter_Copies(thisType)); + if (NS_FAILED(rv)) return PR_TRUE; + if (PL_strcasecmp(entry->hostname, thisHostname)==0 && - NS_SUCCEEDED(server->QueryInterface(*(entry->iid), (void **)&dummy))) { - NS_RELEASE(dummy); - entry->servers->AppendElement(aElement); + PL_strcmp(entry->username, username)==0 && + PL_strcmp(entry->type, thisType)==0) { + entry->server = server; + NS_ADDREF(entry->server); + return PR_FALSE; // stop on first find } return PR_TRUE; diff --git a/mailnews/base/util/nsMsgFolder.cpp b/mailnews/base/util/nsMsgFolder.cpp index 2bddf8657b1..8dfa5b88529 100644 --- a/mailnews/base/util/nsMsgFolder.cpp +++ b/mailnews/base/util/nsMsgFolder.cpp @@ -306,21 +306,24 @@ NS_IMETHODIMP nsMsgFolder::GetServer(nsIMsgIncomingServer ** aServer) rv = session->GetAccountManager(getter_AddRefs(accountManager)); if(NS_FAILED(rv)) return rv; - char * hostname = nsnull; - rv = GetHostName(&hostname); + char * hostname = nsnull; + rv = GetHostname(&hostname); if(NS_FAILED(rv)) return rv; - nsCOMPtr servers; - rv = accountManager->FindServersByHostname(hostname, - GetIncomingServerType(), - getter_AddRefs(servers)); + char * username = nsnull; + rv = GetUsername(&username); + if (NS_FAILED(rv)) return rv; + + nsIMsgIncomingServer *server; + rv = accountManager->FindServer(username, + hostname, + GetIncomingServerType(), + &server); + PR_FREEIF(username); PR_FREEIF(hostname); if (NS_FAILED(rv)) return rv; - - // mscott: this is pretty bogus....we should be required by FindServers - // to pass in enough information to uniquely identify ONE - // server. we need at least the user name and host name. - m_server = do_QueryInterface(servers->ElementAt(0)); + + m_server = server; } if (aServer) @@ -1249,7 +1252,8 @@ NS_IMETHODIMP nsMsgFolder::UserNeedsToAuthenticateForFolder(PRBool displayOnly, return NS_OK; } -NS_IMETHODIMP nsMsgFolder::GetUsersName(char **userName) +#if 0 +NS_IMETHODIMP nsMsgFolder::GetUsername(char **userName) { if(!userName) return NS_ERROR_NULL_POINTER; @@ -1258,7 +1262,7 @@ NS_IMETHODIMP nsMsgFolder::GetUsersName(char **userName) return NS_OK; } -NS_IMETHODIMP nsMsgFolder::GetHostName(char **hostName) +NS_IMETHODIMP nsMsgFolder::GetHostname(char **hostName) { if(!hostName) return NS_ERROR_NULL_POINTER; @@ -1266,6 +1270,7 @@ NS_IMETHODIMP nsMsgFolder::GetHostName(char **hostName) *hostName = ""; return NS_OK; } +#endif NS_IMETHODIMP nsMsgFolder::GetNewMessages() { diff --git a/mailnews/base/util/nsMsgFolder.h b/mailnews/base/util/nsMsgFolder.h index ea454d2187d..7244e26c432 100644 --- a/mailnews/base/util/nsMsgFolder.h +++ b/mailnews/base/util/nsMsgFolder.h @@ -254,9 +254,11 @@ public: NS_IMETHOD RememberPassword(const char *password); NS_IMETHOD GetRememberedPassword(char ** password); NS_IMETHOD UserNeedsToAuthenticateForFolder(PRBool displayOnly, PRBool *needsAuthenticate); - NS_IMETHOD GetUsersName(char **userName); - NS_IMETHOD GetHostName(char **hostName); - +#if 0 + NS_IMETHOD GetUsername(char **userName); + NS_IMETHOD GetHostname(char **hostName); +#endif + virtual nsresult GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDatabase **db) = 0; NS_IMETHOD DeleteMessages(nsISupportsArray *messages, nsITransactionManager *txnMgr, PRBool deleteStorage) = 0; @@ -287,7 +289,7 @@ protected: // we use it to get the IID of the incoming server for the derived folder. // w/out a function like this we would have to implement GetServer in each // derived folder class. - virtual const nsIID& GetIncomingServerType() = 0; + virtual const char* GetIncomingServerType() = 0; protected: nsString mName; diff --git a/mailnews/imap/src/nsImapIncomingServer.cpp b/mailnews/imap/src/nsImapIncomingServer.cpp index 4ec0198c350..8738b27bbfc 100644 --- a/mailnews/imap/src/nsImapIncomingServer.cpp +++ b/mailnews/imap/src/nsImapIncomingServer.cpp @@ -36,6 +36,7 @@ #include "prmem.h" #include "plstr.h" +#include "nsXPIDLString.h" static NS_DEFINE_CID(kCImapHostSessionList, NS_IIMAPHOSTSESSIONLIST_CID); static NS_DEFINE_CID(kImapProtocolCID, NS_IMAPPROTOCOL_CID); @@ -129,18 +130,17 @@ NS_IMETHODIMP nsImapIncomingServer::SetKey(char * aKey) // override nsMsgIncomi NS_IMETHODIMP nsImapIncomingServer::GetServerURI(char ** aServerURI) { nsresult rv = NS_OK; - nsString2 serverUri("imap://", eOneByte); - char * hostName = nsnull; - rv = GetHostName(&hostName); - if (NS_FAILED(rv)) - return rv; - serverUri += hostName; - if (aServerURI) - *aServerURI = PL_strdup(serverUri.GetBuffer()); + nsXPIDLCString hostname; + rv = GetHostName(getter_Copies(hostname)); + nsXPIDLCString username; + rv = GetUsername(getter_Copies(username)); + + if (NS_FAILED(rv)) return rv; - PR_FREEIF(hostName); + *aServerURI = PR_smprintf("imap://%s@%s", (const char*)username, + (const char*)hostname); return rv; } diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index e987fe0e220..bb871dcce88 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -585,7 +585,7 @@ NS_IMETHODIMP nsImapMailFolder::GetName(char ** name) if (mDepth == 0) { char *hostName = nsnull; - GetHostName(&hostName); + GetHostname(&hostName); SetName(hostName); PR_FREEIF(hostName); m_haveReadNameFromDB = PR_TRUE; @@ -626,7 +626,7 @@ NS_IMETHODIMP nsImapMailFolder::GetPrettyName(char ** prettyName) { if (mDepth == 1) { char *hostName = nsnull; - GetHostName(&hostName); + GetHostname(&hostName); *prettyName = PL_strdup(hostName); PR_FREEIF(hostName); } @@ -726,36 +726,31 @@ NS_IMETHODIMP nsImapMailFolder::GetSizeOnDisk(PRUint32 * size) return rv; } -NS_IMETHODIMP nsImapMailFolder::GetUsersName(char** userName) +NS_IMETHODIMP nsImapMailFolder::GetUsername(char** userName) { nsresult rv = NS_ERROR_NULL_POINTER; NS_PRECONDITION (userName, "Oops ... null userName pointer"); if (!userName) return rv; - else - *userName = nsnull; -#if 1 // for now - nsCOMPtr server; - rv = GetServer(getter_AddRefs(server)); - - if (NS_SUCCEEDED(rv)) - rv = server->GetUsername(userName); -#else // **** for the future - nsCOMPtr aFolder = do_QueryInterface(this, &rv); - if (NS_FAILED(rv)) return rv; + + *userName = nsnull; + char *uri = nsnull; - rv = aFolder->GetURI(&uri); + rv = GetURI(&uri); if (NS_FAILED(rv)) return rv; + nsAutoString aName = uri; PR_FREEIF(uri); if (aName.Find(kImapRootURI) != 0) return NS_ERROR_FAILURE; + aName.Cut(0, PL_strlen(kImapRootURI)); while (aName[0] == '/') aName.Cut(0, 1); PRInt32 userEnd = aName.Find('@'); if (userEnd < 1) return NS_ERROR_NULL_POINTER; + aName.SetLength(userEnd); char *tmpCString = aName.ToNewCString(); if (tmpCString && *tmpCString) @@ -764,13 +759,10 @@ NS_IMETHODIMP nsImapMailFolder::GetUsersName(char** userName) rv = NS_OK; delete []tmpCString; } - return rv; -#endif - return rv; } -NS_IMETHODIMP nsImapMailFolder::GetHostName(char** hostName) +NS_IMETHODIMP nsImapMailFolder::GetHostname(char** hostName) { nsresult rv = NS_ERROR_NULL_POINTER; @@ -871,7 +863,7 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages, nsString2 uri("", eOneByte); char* hostName = nsnull; - rv = GetHostName(&hostName); + rv = GetHostname(&hostName); if (NS_FAILED(rv)) return rv; uri.Append(kImapRootURI); @@ -1031,7 +1023,11 @@ NS_IMETHODIMP nsImapMailFolder::PossibleImapMailbox( nsAutoString uri ((const char *)"", eOneByte); uri.Append(kImapRootURI); uri.Append('/'); - + + char *username; + GetUsername(&username); + uri.Append(username); + uri.Append('@'); uri.Append(aSpec->hostName); #if 0 @@ -2148,8 +2144,8 @@ PRBool nsImapMailFolder::ShowDeletedMessages() { char *hostName = nsnull; char *userName = nsnull; - GetHostName(&hostName); - GetUsersName(&userName); + GetHostname(&hostName); + GetUsername(&userName); err = hostSession->GetShowDeletedMessagesForHost(hostName, userName, rv); PR_FREEIF(hostName); PR_FREEIF(userName); @@ -2170,9 +2166,9 @@ PRBool nsImapMailFolder::DeleteIsMoveToTrash() { char *hostName = nsnull; char *userName = nsnull; - GetHostName(&hostName); - GetUsersName(&userName); - nsresult err = hostSession->GetDeleteIsMoveToTrashForHost(hostName, userName, rv); + GetHostname(&hostName); + GetUsername(&userName); + err = hostSession->GetDeleteIsMoveToTrashForHost(hostName, userName, rv); PR_FREEIF(hostName); PR_FREEIF(userName); } @@ -2184,7 +2180,6 @@ nsresult nsImapMailFolder::GetTrashFolder(nsIMsgFolder **pTrashFolder) if (!pTrashFolder) return NS_ERROR_NULL_POINTER; - nsIMsgFolder *foundTrash = NULL; nsCOMPtr rootFolder; nsresult rv = GetRootFolder(getter_AddRefs(rootFolder)); if(NS_SUCCEEDED(rv)) diff --git a/mailnews/imap/src/nsImapMailFolder.h b/mailnews/imap/src/nsImapMailFolder.h index 6ff91e971b4..720796b3ecd 100644 --- a/mailnews/imap/src/nsImapMailFolder.h +++ b/mailnews/imap/src/nsImapMailFolder.h @@ -103,8 +103,8 @@ public: NS_IMETHOD GetSizeOnDisk(PRUint32 * size); - NS_IMETHOD GetUsersName(char** userName); - NS_IMETHOD GetHostName(char** hostName); + NS_IMETHOD GetUsername(char** userName); + NS_IMETHOD GetHostname(char** hostName); NS_IMETHOD UserNeedsToAuthenticateForFolder(PRBool displayOnly, PRBool *authenticate); NS_IMETHOD RememberPassword(const char *password); NS_IMETHOD GetRememberedPassword(char ** password); @@ -286,7 +286,7 @@ protected: nsresult GetDatabase(); - virtual const nsIID& GetIncomingServerType() {return nsIImapIncomingServer::GetIID();} + virtual const char *GetIncomingServerType() {return "imap";} nsNativeFileSpec *m_pathName; PRBool m_initialized; diff --git a/mailnews/imap/src/nsImapService.cpp b/mailnews/imap/src/nsImapService.cpp index 05f3031d764..d6a26173639 100644 --- a/mailnews/imap/src/nsImapService.cpp +++ b/mailnews/imap/src/nsImapService.cpp @@ -103,7 +103,7 @@ nsImapService::GetFolderName(nsIMsgFolder* aImapFolder, rv = aFolder->GetURI(&uri); if (NS_FAILED(rv)) return rv; char * hostname = nsnull; - rv = aImapFolder->GetHostName(&hostname); + rv = aImapFolder->GetHostname(&hostname); if (NS_FAILED(rv)) return rv; nsString name; rv = nsImapURI2FullName(kImapRootURI, hostname, uri, name); @@ -335,9 +335,9 @@ nsImapService::CreateStartOfImapUrl(nsIImapUrl * &imapUrl, char *hostname = nsnull; char *username = nsnull; - rv = aImapMailFolder->GetHostName(&hostname); + rv = aImapMailFolder->GetHostname(&hostname); if (NS_FAILED(rv)) return rv; - rv = aImapMailFolder->GetUsersName(&username); + rv = aImapMailFolder->GetUsername(&username); if (NS_FAILED(rv)) { PR_FREEIF(hostname); @@ -359,7 +359,7 @@ nsImapService::CreateStartOfImapUrl(nsIImapUrl * &imapUrl, #if 0 urlSpec.Append(username); urlSpec.Append('@'); -#endif +#endif urlSpec.Append(hostname); // *** jefft - force to parse the urlSpec in order to search for // the correct incoming server @@ -990,22 +990,22 @@ nsImapService::OnlineMessageCopy(nsIEventQueue* aClientEventQueue, nsresult rv = NS_ERROR_FAILURE; char *srcHostname = nsnull, *srcUsername = nsnull; char *dstHostname = nsnull, *dstUsername = nsnull; - rv = aSrcFolder->GetHostName(&srcHostname); + rv = aSrcFolder->GetHostname(&srcHostname); if (NS_FAILED(rv)) return rv; - rv = aDstFolder->GetHostName(&dstHostname); + rv = aDstFolder->GetHostname(&dstHostname); if (NS_FAILED(rv)) { PR_FREEIF(srcHostname); return rv; } - rv = aSrcFolder->GetUsersName(&srcUsername); + rv = aSrcFolder->GetUsername(&srcUsername); if (NS_FAILED(rv)) { PR_FREEIF(srcHostname); PR_FREEIF(dstHostname); return rv; } - rv = aDstFolder->GetUsersName(&dstUsername); + rv = aDstFolder->GetUsername(&dstUsername); if (NS_FAILED(rv)) { PR_FREEIF(srcHostname); diff --git a/mailnews/imap/src/nsImapUrl.cpp b/mailnews/imap/src/nsImapUrl.cpp index 77990998357..e09835bb359 100644 --- a/mailnews/imap/src/nsImapUrl.cpp +++ b/mailnews/imap/src/nsImapUrl.cpp @@ -511,7 +511,15 @@ nsresult nsImapUrl::ParseURL(const nsString& aSpec, const nsIURL* aURL) // Host name follows protocol for http style urls const char* cp0 = cp; - cp = PL_strpbrk(cp, "/:"); + cp = PL_strchr(cp0, '@'); + + if (cp) { + // we have a username between cp0 and cp + m_userName = PL_strndup(cp0, (cp - cp0)); + cp0 = cp+1; + } + + cp = PL_strpbrk(cp0, "/:"); if (nsnull == cp) { // There is only a host name @@ -519,8 +527,7 @@ nsresult nsImapUrl::ParseURL(const nsString& aSpec, const nsIURL* aURL) m_host = (char*) PR_Malloc(hlen + 1); PL_strcpy(m_host, cp0); } - else - { + else { PRInt32 hlen = cp - cp0; m_host = (char*) PR_Malloc(hlen + 1); PL_strncpy(m_host, cp0, hlen); @@ -561,15 +568,14 @@ nsresult nsImapUrl::ParseURL(const nsString& aSpec, const nsIURL* aURL) rv = session->GetAccountManager(getter_AddRefs(accountManager)); if(NS_FAILED(rv)) return rv; - nsCOMPtr servers; - rv = accountManager->FindServersByHostname(m_host, - nsIImapIncomingServer::GetIID(), - getter_AddRefs(servers)); - if (NS_FAILED(rv)) return rv; - nsCOMPtr aSupport = - getter_AddRefs(servers->ElementAt(0)); - nsCOMPtr server (do_QueryInterface(aSupport)); + nsCOMPtr server; + rv = accountManager->FindServer(m_userName, + m_host, + "imap", + getter_AddRefs(server)); if (NS_FAILED(rv)) return rv; + // can't do an addref because it's private to nsIURL, so use + // do_QueryInterface instead m_server = do_QueryInterface(server); } diff --git a/mailnews/imap/src/nsImapUtils.cpp b/mailnews/imap/src/nsImapUtils.cpp index a57228cdbff..1efd52d3deb 100644 --- a/mailnews/imap/src/nsImapUtils.cpp +++ b/mailnews/imap/src/nsImapUtils.cpp @@ -33,40 +33,29 @@ static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID); nsresult -nsGetImapRoot(const char* hostname, nsFileSpec &result) +nsGetImapServer(const char* username, const char* hostname, + nsIMsgIncomingServer ** aResult) { nsresult rv = NS_OK; NS_WITH_SERVICE(nsIMsgMailSession, session, kMsgMailSessionCID, &rv); if (NS_FAILED(rv)) return rv; + nsCOMPtr accountManager; rv = session->GetAccountManager(getter_AddRefs(accountManager)); if(NS_FAILED(rv)) return rv; - nsCOMPtr servers; - rv = accountManager->FindServersByHostname(hostname, - nsIImapIncomingServer::GetIID(), - getter_AddRefs(servers)); + nsCOMPtr server; + rv = accountManager->FindServer(username, + hostname, + "imap", + getter_AddRefs(server)); if (NS_FAILED(rv)) return rv; - nsCOMPtr aSupport = getter_AddRefs(servers->ElementAt(0)); - nsCOMPtr server(do_QueryInterface(aSupport)); + *aResult = server; + NS_ADDREF(*aResult); - char *localPath = nsnull; - - if (server) { - rv = server->GetLocalPath(&localPath); - - if (NS_SUCCEEDED(rv)) { - nsFilePath dirPath(localPath, PR_TRUE); - nsFileSpec dirSpec(dirPath); // recursive create the parent directory - - result = localPath; - result.CreateDirectory(); - PL_strfree(localPath); - } - } return rv; } @@ -104,27 +93,55 @@ nsImapURI2Path(const char* rootURI, const char* uriStr, nsFileSpec& pathResult) // skip past all // while (uri[hostStart]=='/') hostStart++; - // cut imap://hostname/folder -> hostname/folder + // cut imap://[userid@]hostname/folder -> [userid@]hostname/folder nsAutoString hostname; uri.Right(hostname, uri.Length() - hostStart); - PRInt32 hostEnd = hostname.Find('/'); + nsAutoString username(""); + PRInt32 atPos = hostname.Find('@'); + if (atPos != -1) { + hostname.Left(username, atPos); + hostname.Cut(0, atPos+1); + } + nsAutoString folder; // folder comes after the hostname, after the '/' + // cut off first '/' and everything following it // hostname/folder -> hostname + PRInt32 hostEnd = hostname.Find('/'); if (hostEnd > 0) { hostname.Right(folder, hostname.Length() - hostEnd - 1); hostname.Truncate(hostEnd); } - char *hostchar = hostname.ToNewCString(); - rv = nsGetImapRoot(hostchar, pathResult); - - delete[] hostchar; + char *userchar = username.ToNewCString(); + char *hostchar = hostname.ToNewCString(); + nsCOMPtr server; + rv = nsGetImapServer(userchar, + hostchar, + getter_AddRefs(server)); + delete[] userchar; + delete[] hostchar; + + if (NS_FAILED(rv)) return rv; + + char *localPath = nsnull; + if (server) { + rv = server->GetLocalPath(&localPath); + + if (NS_SUCCEEDED(rv)) { + nsFilePath dirPath(localPath, PR_TRUE); + nsFileSpec dirSpec(dirPath); // recursive create the parent directory + + pathResult = localPath; + pathResult.CreateDirectory(); + PL_strfree(localPath); + } + } if (NS_FAILED(rv)) { diff --git a/mailnews/imap/src/nsImapUtils.h b/mailnews/imap/src/nsImapUtils.h index 17870fcd79f..9880e7eb730 100644 --- a/mailnews/imap/src/nsImapUtils.h +++ b/mailnews/imap/src/nsImapUtils.h @@ -25,9 +25,6 @@ static const char kImapRootURI[] = "imap:/"; static const char kImapMessageRootURI[] = "imap_message:/"; -extern nsresult -nsGetImapRoot(const char* hostname, nsFileSpec &result); - extern nsresult nsImapURI2Path(const char* rootURI, const char* uriStr, nsFileSpec& pathResult); diff --git a/mailnews/local/src/nsLocalMailFolder.cpp b/mailnews/local/src/nsLocalMailFolder.cpp index 282076d3260..358f09b057e 100644 --- a/mailnews/local/src/nsLocalMailFolder.cpp +++ b/mailnews/local/src/nsLocalMailFolder.cpp @@ -897,15 +897,12 @@ NS_IMETHODIMP nsMsgLocalMailFolder::GetSizeOnDisk(PRUint32* size) return NS_OK; } -NS_IMETHODIMP nsMsgLocalMailFolder::GetUsersName(char** userName) +NS_IMETHODIMP nsMsgLocalMailFolder::GetUsername(char** userName) { -#ifdef HAVE_PORT - return NET_GetPopUsername(); -#endif - return NS_OK; + return nsGetMailboxUserName(kMailboxRootURI, mURI, userName); } -NS_IMETHODIMP nsMsgLocalMailFolder::GetHostName(char** hostName) +NS_IMETHODIMP nsMsgLocalMailFolder::GetHostname(char** hostName) { nsresult rv; char *host; diff --git a/mailnews/local/src/nsLocalMailFolder.h b/mailnews/local/src/nsLocalMailFolder.h index 7cdf3cd6a2d..5ed4d0ffd26 100644 --- a/mailnews/local/src/nsLocalMailFolder.h +++ b/mailnews/local/src/nsLocalMailFolder.h @@ -87,8 +87,8 @@ public: NS_IMETHOD GetSizeOnDisk(PRUint32* size); - NS_IMETHOD GetUsersName(char** userName); - NS_IMETHOD GetHostName(char** hostName); + NS_IMETHOD GetUsername(char** userName); + NS_IMETHOD GetHostname(char** hostName); NS_IMETHOD UserNeedsToAuthenticateForFolder(PRBool displayOnly, PRBool *authenticate); NS_IMETHOD RememberPassword(const char *password); NS_IMETHOD GetRememberedPassword(char ** password); @@ -129,7 +129,7 @@ protected: nsresult DeleteMessage(nsIMessage *message, nsITransactionManager *txnMgr, PRBool deleteStorage); nsresult MoveMessageToTrash(nsIMessage *message, nsIMsgFolder *trashFolder); - virtual const nsIID& GetIncomingServerType() {return nsIPop3IncomingServer::GetIID();} + virtual const char* GetIncomingServerType() {return "pop3";} protected: nsNativeFileSpec *mPath; diff --git a/mailnews/local/src/nsLocalUtils.cpp b/mailnews/local/src/nsLocalUtils.cpp index 206249b5a73..eb6c5177098 100644 --- a/mailnews/local/src/nsLocalUtils.cpp +++ b/mailnews/local/src/nsLocalUtils.cpp @@ -37,8 +37,8 @@ static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID); // - 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) -nsresult -nsGetMailboxRoot(const char *hostname, nsFileSpec &result) +static nsresult +nsGetMailboxServer(const char *username, const char *hostname, nsIMsgIncomingServer** aResult) { nsresult rv = NS_OK; @@ -50,73 +50,62 @@ nsGetMailboxRoot(const char *hostname, nsFileSpec &result) if (NS_FAILED(rv)) return rv; // find all pop hosts matching the given hostname - nsCOMPtr hosts; - rv = accountManager->FindServersByHostname(hostname, - nsIPop3IncomingServer::GetIID(), - getter_AddRefs(hosts)); - + nsCOMPtr server; + rv = accountManager->FindServer(username, + hostname, + "pop3", + getter_AddRefs(server)); + if (NS_FAILED(rv)) return rv; - // use enumeration function to find the first Pop server - nsCOMPtr serverSupports = getter_AddRefs(hosts->ElementAt(0)); - -#ifdef DEBUG_alecf - if (!serverSupports) - printf("Huh, serverSupports returned nsnull\n"); -#endif - - // if there are no pop servers, how did we get here? - if (! serverSupports) - return NS_ERROR_UNEXPECTED; - - nsCOMPtr server = do_QueryInterface(serverSupports); - - // this had better be a nsIMsgIncomingServer, otherwise - // FindServersByHostname is broken or we got some weird object back - PR_ASSERT(server); + *aResult = server; + NS_ADDREF(*aResult); - // now ask the server what it's root is - char *localPath; - rv = server->GetLocalPath(&localPath); - if (NS_SUCCEEDED(rv)) - result = localPath; - - if (localPath) PL_strfree(localPath); return rv; } -// given rootURI and rootURI##folder, return on-disk path of folder -nsresult -nsLocalURI2Path(const char* rootURI, const char* uriStr, - nsFileSpec& pathResult) +static nsresult +nsLocalURI2Server(const char* uriStr, + nsIMsgIncomingServer ** aResult) { + nsresult rv; - nsAutoString sbdSep; - rv = nsGetMailFolderSeparator(sbdSep); - if (NS_FAILED(rv)) return rv; - - nsAutoString uri = uriStr; - if (uri.Find(rootURI) != 0) // if doesn't start with rootURI - return NS_ERROR_FAILURE; - - // verify that rootURI starts with "mailbox:/" or "mailbox_message:/" - if ((PL_strcmp(rootURI, kMailboxRootURI) != 0) && - (PL_strcmp(rootURI, kMailboxMessageRootURI) != 0)) { - pathResult = nsnull; - return NS_ERROR_FAILURE; - } // start parsing the uriStr const char* curPos = uriStr; - // skip past schema + // skip past schema xxx:// while (*curPos != ':') curPos++; curPos++; while (*curPos == '/') curPos++; - char *slashPos = PL_strchr(curPos, '/'); + // extract userid from userid@hostname... + // this is so amazingly ugly, please forgive me.... + // I'll fix this post-M7 -alecf@netscape.com + char *atPos = PL_strchr(curPos, '@'); + NS_ASSERTION(atPos!=nsnull, "URI with no userid!"); + int length; + if (atPos) + length = (atPos - curPos) + 1; + else { + length = 1; + } + + char *username = new char[length]; + if (!username) return NS_ERROR_OUT_OF_MEMORY; + + if (atPos) { + PL_strncpyz(username, curPos, length); + curPos = atPos; + curPos++; + } + else + username[0] = '\0'; + + // extract hostname + char *slashPos = PL_strchr(curPos, '/'); // if there are no more /'s then we just copy the rest of the string if (slashPos) @@ -130,17 +119,64 @@ nsLocalURI2Path(const char* rootURI, const char* uriStr, PL_strncpyz(hostname, curPos, length); - // begin pathResult with the mailbox root - rv = nsGetMailboxRoot(hostname, pathResult); + nsCOMPtr server; + rv = nsGetMailboxServer(username, hostname, getter_AddRefs(server)); + delete[] username; delete[] hostname; + + *aResult = server; + NS_ADDREF(*aResult); + + return rv; +} + +// given rootURI and rootURI##folder, return on-disk path of folder +nsresult +nsLocalURI2Path(const char* rootURI, const char* uriStr, + nsFileSpec& pathResult) +{ + nsresult rv; + + // verify that rootURI starts with "mailbox:/" or "mailbox_message:/" + if ((PL_strcmp(rootURI, kMailboxRootURI) != 0) && + (PL_strcmp(rootURI, kMailboxMessageRootURI) != 0)) { + pathResult = nsnull; + return NS_ERROR_FAILURE; + } + + // verify that uristr starts with rooturi + nsAutoString uri = uriStr; + if (uri.Find(rootURI) != 0) + return NS_ERROR_FAILURE; + + + nsCOMPtr 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 + char *localPath; + rv = server->GetLocalPath(&localPath); + if (NS_SUCCEEDED(rv)) + pathResult = localPath; - if (slashPos) { + if (localPath) PL_strfree(localPath); + + const char *curPos = uriStr + PL_strlen(rootURI); + if (curPos) { + // advance past hostname - curPos=slashPos; - curPos++; + while ((*curPos)=='/') curPos++; + while (*curPos && (*curPos)!='/') curPos++; + while ((*curPos)=='/') curPos++; + // get the seperator + nsAutoString sbdSep; + rv = nsGetMailFolderSeparator(sbdSep); + // for each token in between the /'s, put a .sbd on the end and // append to the path char *newStr=nsnull; @@ -239,38 +275,62 @@ nsresult nsBuildLocalMessageURI(const char *baseURI, PRUint32 key, char** uri) return NS_OK; } -nsresult nsGetMailboxHostName(const char *rootURI, const char *uriStr, char **hostName) +nsresult +nsGetMailboxHostName(const char *rootURI, const char *uriStr, char **hostName) { if(!hostName) return NS_ERROR_NULL_POINTER; + 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 nsAutoString uri = uriStr; - if (uri.Find(rootURI) != 0) // if doesn't start with rootURI + if (uri.Find(rootURI) != 0) return NS_ERROR_FAILURE; - // start parsing the uriStr - const char* curPos = uriStr; + nsCOMPtr server; + rv = nsLocalURI2Server(uriStr, getter_AddRefs(server)); - // skip past schema - while (*curPos != ':') curPos++; - curPos++; - while (*curPos == '/') curPos++; - - char *slashPos = PL_strchr(curPos, '/'); - int length; - - // if there are no more /'s then we just copy the rest of the string - if (slashPos) - length = (slashPos - curPos) + 1; - else - length = PL_strlen(curPos) + 1; - - *hostName = new char[length]; - if(!*hostName) - return NS_ERROR_OUT_OF_MEMORY; - - PL_strncpyz(*hostName, curPos, length); - - return NS_OK; + if (NS_FAILED(rv)) + return rv; + + return server->GetHostName(hostName); +} + + +nsresult nsGetMailboxUserName(const char *rootURI, const char* uriStr, + char **userName) +{ + + + if(!userName) + return NS_ERROR_NULL_POINTER; + + 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 + nsAutoString uri = uriStr; + if (uri.Find(rootURI) != 0) + return NS_ERROR_FAILURE; + + nsCOMPtr server; + rv = nsLocalURI2Server(uriStr, getter_AddRefs(server)); + + if (NS_FAILED(rv)) + return rv; + + return server->GetUsername(userName); } diff --git a/mailnews/local/src/nsLocalUtils.h b/mailnews/local/src/nsLocalUtils.h index 3c2ee175149..0846a4dc257 100644 --- a/mailnews/local/src/nsLocalUtils.h +++ b/mailnews/local/src/nsLocalUtils.h @@ -25,9 +25,6 @@ static const char kMailboxRootURI[] = "mailbox:/"; static const char kMailboxMessageRootURI[] = "mailbox_message:/"; -nsresult -nsGetMailboxRoot(const char* hostname, nsFileSpec &result); - nsresult nsLocalURI2Path(const char* rootURI, const char* uriStr, nsFileSpec& pathResult); @@ -40,5 +37,7 @@ nsParseLocalMessageURI(const char* uri, nsString& folderURI, PRUint32 *key); nsresult nsBuildLocalMessageURI(const char* baseURI, PRUint32 key, char** uri); nsresult nsGetMailboxHostName(const char *rootURI, const char *uriStr, char **hostName); +nsresult +nsGetMailboxUserName(const char *rootURI, const char *uriStr, char **userName); #endif //NS_LOCALUTILS_H diff --git a/mailnews/local/src/nsPop3IncomingServer.cpp b/mailnews/local/src/nsPop3IncomingServer.cpp index ff3b1ba1878..cb183f01957 100644 --- a/mailnews/local/src/nsPop3IncomingServer.cpp +++ b/mailnews/local/src/nsPop3IncomingServer.cpp @@ -28,6 +28,7 @@ #include "prmem.h" #include "plstr.h" #include "prprf.h" +#include "nsXPIDLString.h" static NS_DEFINE_CID(kCPop3ServiceCID, NS_POP3SERVICE_CID); @@ -97,14 +98,18 @@ nsresult nsPop3IncomingServer::GetServerURI(char **uri) { nsresult rv; - char *hostname; - - rv = GetHostName(&hostname); + + nsXPIDLCString username; + rv = GetUsername(getter_Copies(username)); if (NS_FAILED(rv)) return rv; - *uri = PR_smprintf("mailbox://%s", hostname); + nsXPIDLCString hostname; + rv = GetHostName(getter_Copies(hostname)); + if (NS_FAILED(rv)) return rv; - PR_Free(hostname); + *uri = PR_smprintf("mailbox://%s@%s", + (const char *)username, + (const char *)hostname); return rv; } diff --git a/mailnews/news/src/nsNewsFolder.cpp b/mailnews/news/src/nsNewsFolder.cpp index 3c30682d808..446295a7b8d 100644 --- a/mailnews/news/src/nsNewsFolder.cpp +++ b/mailnews/news/src/nsNewsFolder.cpp @@ -303,7 +303,7 @@ nsMsgNewsFolder::CreateSubFolders(nsFileSpec &path) nsresult rv = NS_OK; char *hostname; - rv = GetHostName(&hostname); + rv = GetHostname(&hostname); if (NS_FAILED(rv)) return rv; if (isNewsHost()) { @@ -971,13 +971,13 @@ NS_IMETHODIMP nsMsgNewsFolder::GetSizeOnDisk(PRUint32 *size) return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP nsMsgNewsFolder::GetUsersName(char** userName) +NS_IMETHODIMP nsMsgNewsFolder::GetUsername(char** userName) { - PR_ASSERT(0); - return NS_ERROR_NOT_IMPLEMENTED; + *userName = PL_strdup(""); + return NS_OK; } -NS_IMETHODIMP nsMsgNewsFolder::GetHostName(char** hostName) +NS_IMETHODIMP nsMsgNewsFolder::GetHostname(char** hostName) { nsresult rv = NS_OK; @@ -1052,7 +1052,7 @@ NS_IMETHODIMP nsMsgNewsFolder::DeleteMessages(nsISupportsArray *messages, if (NS_SUCCEEDED(rv) && nntpService) { char *hostname; - rv = GetHostName(&hostname); + rv = GetHostname(&hostname); if (NS_FAILED(rv)) return rv; char *newsgroupname; rv = GetName(&newsgroupname); diff --git a/mailnews/news/src/nsNewsFolder.h b/mailnews/news/src/nsNewsFolder.h index db7a1421006..5512d49f228 100644 --- a/mailnews/news/src/nsNewsFolder.h +++ b/mailnews/news/src/nsNewsFolder.h @@ -78,8 +78,8 @@ public: NS_IMETHOD GetSizeOnDisk(PRUint32 *size); - NS_IMETHOD GetUsersName(char** userName); - NS_IMETHOD GetHostName(char** hostName); + NS_IMETHOD GetUsername(char** userName); + NS_IMETHOD GetHostname(char** hostName); NS_IMETHOD UserNeedsToAuthenticateForFolder(PRBool displayOnly, PRBool *authenticate); NS_IMETHOD RememberPassword(const char *password); NS_IMETHOD GetRememberedPassword(char ** password); @@ -116,7 +116,9 @@ protected: #ifdef USE_NEWSRC_MAP_FILE nsresult MapHostToNewsrcFile(char *newshostname, nsFileSpec &fatFile, nsFileSpec &newsrcFile); #endif - virtual const nsIID& GetIncomingServerType() {return nsINntpIncomingServer::GetIID();} + + virtual const char *GetIncomingServerType() {return "nntp";} + nsByteArray m_inputStream; protected: diff --git a/mailnews/news/src/nsNewsUtils.cpp b/mailnews/news/src/nsNewsUtils.cpp index 377b60252cc..70ed3842b3e 100644 --- a/mailnews/news/src/nsNewsUtils.cpp +++ b/mailnews/news/src/nsNewsUtils.cpp @@ -30,8 +30,9 @@ static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID); -nsresult -nsGetNewsRoot(const char *hostname, nsFileSpec &result) +static nsresult +nsGetNewsServer(const char* username, const char *hostname, + nsIMsgIncomingServer** aResult) { nsresult rv = NS_OK; @@ -42,39 +43,16 @@ nsGetNewsRoot(const char *hostname, nsFileSpec &result) rv = session->GetAccountManager(getter_AddRefs(accountManager)); if (NS_FAILED(rv)) return rv; - // find all news hosts matching the given hostname - nsCOMPtr hosts; - rv = accountManager->FindServersByHostname(hostname, - nsINntpIncomingServer::GetIID(), - getter_AddRefs(hosts)); + // find the news host + nsCOMPtr server; + rv = accountManager->FindServer(username, + hostname, + "nntp", + getter_AddRefs(server)); if (NS_FAILED(rv)) return rv; - // use enumeration function to find the first nntp server - nsISupports *serverSupports = hosts->ElementAt(0); - -#ifdef DEBUG_NEWS - if (hosts->Count() <= 0) - printf("Augh, no nntp server named %s?\n", hostname); - if (!serverSupports) - printf("Huh, serverSupports returned nsnull\n"); -#endif - - // if there are no nntp servers, how did we get here? - if (! serverSupports) return NS_ERROR_UNEXPECTED; - - nsCOMPtr server = do_QueryInterface(serverSupports); - - // this had better be a nsIMsgIncomingServer, otherwise - // FindServersByHostname is broken or we got some weird object back - PR_ASSERT(server); - - // now ask the server what it's root is - char *localPath; - rv = server->GetLocalPath(&localPath); - if (NS_SUCCEEDED(rv)) { - result = localPath; - PL_strfree(localPath); - } + *aResult = server; + NS_ADDREF(*aResult); return rv; } @@ -144,12 +122,27 @@ nsNewsURI2Path(const char* rootURI, const char* uriStr, nsFileSpec& pathResult) // skip past all // while (uri[hostStart]=='/') hostStart++; - // cut news://hostname/newsgroup -> hostname/newsgroup + // cut news://[username@]hostname/newsgroup -> username@hostname/newsgroup nsAutoString hostname (eOneByte); uri.Right(hostname, uri.Length() - hostStart); PRInt32 hostEnd = hostname.Find('/'); + PRInt32 atPos = hostname.Find('@'); + nsAutoString username(eOneByte); + + username = ""; + // we have a username here + // XXX do this right, this doesn't work -alecf@netscape.com + if (atPos != -1) { + + hostname.Left(username, hostEnd-atPos); + + username = ""; + + hostEnd = hostname.Find('/'); + } + // newsgroup comes after the hostname, after the '/' nsAutoString newsgroup (eOneByte); @@ -163,13 +156,20 @@ nsNewsURI2Path(const char* rootURI, const char* uriStr, nsFileSpec& pathResult) hostname.Truncate(hostEnd); } - rv = nsGetNewsRoot(hostname.GetBuffer(), pathResult); + nsCOMPtr server; + rv = nsGetNewsServer(username.GetBuffer(), + hostname.GetBuffer(), getter_AddRefs(server)); + // now ask the server what it's root is + char *localPath; + if (NS_SUCCEEDED(rv)) + rv = server->GetLocalPath(&localPath); + if (NS_SUCCEEDED(rv)) { + pathResult = localPath; + } + if (localPath) PL_strfree(localPath); if (NS_FAILED(rv)) { pathResult = nsnull; -#ifdef DEBUG_NEWS - printf("nsGetNewsRoot failed!\n"); -#endif return rv; } @@ -199,12 +199,6 @@ nsNewsURI2Path(const char* rootURI, const char* uriStr, nsFileSpec& pathResult) pathResult += newsgroup; } -#ifdef DEBUG_NEWS - printf("nsGetNewsRoot(%s) = %s\n\tnewsgroup = %s\n", - hostname.GetBuffer(), (const char*)pathResult, - newsgroup.GetBuffer(); -#endif - return NS_OK; } diff --git a/mailnews/news/src/nsNewsUtils.h b/mailnews/news/src/nsNewsUtils.h index 1f1b69a22bf..f886dd448ac 100644 --- a/mailnews/news/src/nsNewsUtils.h +++ b/mailnews/news/src/nsNewsUtils.h @@ -50,9 +50,6 @@ static const char kNewsMessageRootURI[] = "news_message:/"; #endif /* ! XP_UNIX */ -extern nsresult -nsGetNewsRoot(const char* hostname, nsFileSpec &result); - extern nsresult nsGetNewsHostName(const char *rootURI, const char *uriStr, char **hostName); diff --git a/mailnews/news/src/nsNntpIncomingServer.cpp b/mailnews/news/src/nsNntpIncomingServer.cpp index b050cb97174..1a82eeecea0 100644 --- a/mailnews/news/src/nsNntpIncomingServer.cpp +++ b/mailnews/news/src/nsNntpIncomingServer.cpp @@ -17,6 +17,7 @@ */ #include "nsNntpIncomingServer.h" +#include "nsXPIDLString.h" NS_IMPL_ISUPPORTS_INHERITED(nsNntpIncomingServer, nsMsgIncomingServer, @@ -43,14 +44,21 @@ nsresult nsNntpIncomingServer::GetServerURI(char **uri) { nsresult rv; - char *hostname; + + nsXPIDLCString hostname; + rv = GetHostName(getter_Copies(hostname)); + + nsXPIDLCString username; + rv = GetUsername(getter_Copies(username)); - rv = GetHostName(&hostname); if (NS_FAILED(rv)) return rv; - *uri = PR_smprintf("news://%s", hostname); + if ((const char*)username) + *uri = PR_smprintf("news://%s@%s", (const char*)username, + (const char*)hostname); + else + *uri = PR_smprintf("news://%s", (const char*)hostname); - PR_Free(hostname); return rv; }