diff --git a/mailnews/news/public/nsIMsgNewsFolder.idl b/mailnews/news/public/nsIMsgNewsFolder.idl index a221b999d4eb..79a7ccc7b11b 100644 --- a/mailnews/news/public/nsIMsgNewsFolder.idl +++ b/mailnews/news/public/nsIMsgNewsFolder.idl @@ -23,10 +23,16 @@ #include "nsISupports.idl" #include "nsIMsgFolder.idl" +interface nsIMsgWindow; + [scriptable, uuid(3716abe4-f6d4-11d2-86d5-004005263078)] interface nsIMsgNewsFolder : nsISupports { attribute string unreadSetStr; attribute string groupUsername; attribute string groupPassword; + + string getGroupPasswordWithUI(in wstring aPromptString, in wstring aPromptTitle, in nsIMsgWindow aMsgWindow); + string getGroupUsernameWithUI(in wstring aPromptString, in wstring aPromptTitle, in nsIMsgWindow aMsgWindow); + nsIMsgFolder addNewsgroup(in string newsgroupName, in string setStr); }; diff --git a/mailnews/news/public/nsINntpService.idl b/mailnews/news/public/nsINntpService.idl index 661a2609232b..b930ea03ee45 100644 --- a/mailnews/news/public/nsINntpService.idl +++ b/mailnews/news/public/nsINntpService.idl @@ -33,12 +33,12 @@ interface nsIMsgWindow; [scriptable, uuid(4C9F90E0-E19B-11d2-806E-006008128C4E)] interface nsINntpService : nsISupports { - string ConvertNewsgroupsString(in string newsgroupsStr); + string convertNewsgroupsString(in string newsgroupsStr); - nsIURI PostMessage (in nsIFileSpec fileToPost, in string newsgroupNames, in nsIUrlListener aUrlListener); + nsIURI postMessage (in nsIFileSpec fileToPost, in string newsgroupNames, in nsIUrlListener aUrlListener); - nsIURI GetNewNews (in nsINntpIncomingServer nntpServer, in string uri, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow); + nsIURI getNewNews (in nsINntpIncomingServer nntpServer, in string uri, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow); - nsIURI CancelMessages (in string hostname, in string newsgroupname, in nsISupportsArray messages, in nsISupports aConsumer, in nsIUrlListener aUrlListener); + nsIURI cancelMessages (in string hostname, in string newsgroupname, in nsISupportsArray messages, in nsISupports aConsumer, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow); }; diff --git a/mailnews/news/resources/content/news-test.js b/mailnews/news/resources/content/news-test.js index dc23a04d7e0a..19990b0bd5e4 100644 --- a/mailnews/news/resources/content/news-test.js +++ b/mailnews/news/resources/content/news-test.js @@ -34,7 +34,7 @@ function doit() { } if (news) { try { - document.getElementById('result').value = news.ConvertNewsgroupsString(str); + document.getElementById('result').value = news.convertNewsgroupsString(str); } catch (ex) { dump(ex + "\n"); diff --git a/mailnews/news/src/nsNNTPProtocol.cpp b/mailnews/news/src/nsNNTPProtocol.cpp index b4d00fbe059a..762527ba913f 100644 --- a/mailnews/news/src/nsNNTPProtocol.cpp +++ b/mailnews/news/src/nsNNTPProtocol.cpp @@ -82,6 +82,15 @@ #include "nsIRDFResource.h" #include "nsRDFCID.h" +#include "nsIMsgWindow.h" +#include "nsIWebShell.h" +#include "nsIWebShellWindow.h" +#include "nsINetPrompt.h" + +#ifdef DEBUG_sspitzer +#define DEBUG_NEWS 1 +#endif + #define DEFAULT_NEWS_CHUNK_SIZE -1 // ***jt -- the following were pirated from xpcom/io/nsByteBufferInputStream @@ -123,8 +132,7 @@ protected: PRUint32 mLength; }; -/*#define CACHE_NEWSGRP_PASSWORD*/ - +// todo: get rid of this extern "C" { char * NET_SACopy (char **destination, const char *source); @@ -294,7 +302,6 @@ char *stateLabels[] = { (the object that is going to manage the NNTP connections. it would keep track of the connection list.) */ /* PRIVATE XP_List * nntp_connection_list=0; */ -static PRBool net_news_last_username_probably_valid=PR_FALSE; PRInt32 net_NewsChunkSize=DEFAULT_NEWS_CHUNK_SIZE; /* PRIVATE PRInt32 net_news_timeout = 170; */ /* seconds that an idle NNTP conn can live */ @@ -433,7 +440,7 @@ nsDummyBufferStream::QueryInterface(REFNSIID aIID, void** result) return NS_ERROR_NO_INTERFACE; } -nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL) +nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow) : nsMsgProtocol(aURL, nsnull) { m_messageID = nsnull; @@ -441,6 +448,10 @@ nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL) m_cancelNewsgroups = nsnull; m_cancelDistribution = nsnull; m_cancelID = nsnull; + + if (aMsgWindow) { + m_msgWindow = aMsgWindow; + } } nsNNTPProtocol::~nsNNTPProtocol() @@ -545,8 +556,37 @@ nsresult nsNNTPProtocol::Initialize(void) return NS_OK; } +nsresult +nsNNTPProtocol::InitializeNewsFolderFromUri(const char *uri) +{ + nsresult rv; + + NS_ENSURE_ARG_POINTER(uri); + +#ifdef DEBUG_NEWS + printf("InitializeNewsFolderFromUri(%s)\n",uri); +#endif + + NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv); + if (NS_FAILED(rv)) return(rv); + + nsCOMPtr resource; + rv = rdf->GetResource(uri, getter_AddRefs(resource)); + if (NS_FAILED(rv)) return(rv); + + m_newsFolder = do_QueryInterface(resource, &rv); + if (NS_FAILED(rv)) return rv; + + if (!m_newsFolder) return NS_ERROR_FAILURE; + + return NS_OK; +} + + nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) { + NS_ENSURE_ARG_POINTER(aURL); + PRBool bVal = PR_FALSE; nsXPIDLCString group; char *commandSpecificData = nsnull; @@ -555,32 +595,25 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) nsresult rv = NS_OK; m_articleNumber = -1; - if (aURL) - { - rv = aURL->GetHost(getter_Copies(m_hostName)); - if (NS_FAILED(rv)) return rv; - rv = aURL->GetPreHost(getter_Copies(m_userName)); - if (NS_FAILED(rv)) return rv; - - m_runningURL = do_QueryInterface(aURL, &rv); - if (NS_FAILED(rv)) return rv; - m_runningURL->GetNewsAction(&m_newsAction); + rv = aURL->GetHost(getter_Copies(m_hostName)); + if (NS_FAILED(rv)) return rv; + rv = aURL->GetPreHost(getter_Copies(m_userName)); + if (NS_FAILED(rv)) return rv; - // okay, now fill in our event sinks...Note that each getter ref counts before - // it returns the interface to us...we'll release when we are done - m_runningURL->GetNewsgroupList(getter_AddRefs(m_newsgroupList)); - m_runningURL->GetNntpArticleList(getter_AddRefs(m_articleList)); - m_runningURL->GetNntpHost(getter_AddRefs(m_newsHost)); - m_runningURL->GetNewsgroup(getter_AddRefs(m_newsgroup)); - m_runningURL->GetOfflineNewsState(getter_AddRefs(m_offlineNewsState)); - } - else - rv = NS_ERROR_FAILURE; + m_runningURL = do_QueryInterface(aURL, &rv); + if (NS_FAILED(rv)) return rv; + m_runningURL->GetNewsAction(&m_newsAction); - if (NS_FAILED(rv)) - { - goto FAIL; - } + // okay, now fill in our event sinks...Note that each getter ref counts before + // it returns the interface to us...we'll release when we are done + m_runningURL->GetNewsgroupList(getter_AddRefs(m_newsgroupList)); + m_runningURL->GetNntpArticleList(getter_AddRefs(m_articleList)); + m_runningURL->GetNntpHost(getter_AddRefs(m_newsHost)); + m_runningURL->GetNewsgroup(getter_AddRefs(m_newsgroup)); + m_runningURL->GetOfflineNewsState(getter_AddRefs(m_offlineNewsState)); + + + if (NS_FAILED(rv)) goto FAIL; PR_FREEIF(m_messageID); m_messageID = nsnull; @@ -711,15 +744,14 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) news:/GROUP news://HOST/GROUP */ -#ifdef UNREADY_CODE - if (ce->window_id->type != MWContextNews && ce->window_id->type != MWContextNewsMsg - && ce->window_id->type != MWContextMailMsg - && ce->window_id->type != MWContextMail && ce->window_id->type != MWContextMailNewsProgress) - { - *status = -1; - goto FAIL; - } -#endif + + nsXPIDLCString newsgroupURI; + rv = aURL->GetSpec(getter_Copies(newsgroupURI)); + if (NS_FAILED(rv)) return(rv); + + rv = InitializeNewsFolderFromUri((const char *)newsgroupURI); + if (NS_FAILED(rv)) return(rv); + if (PL_strchr (group, '*')) m_typeWanted = LIST_WANTED; else @@ -1111,46 +1143,6 @@ PRInt32 nsNNTPProtocol::NewsResponse(nsIInputStream * inputStream, PRUint32 leng /* authentication required can come at any time */ -#ifdef CACHE_NEWSGRP_PASSWORD - /* - * This is an effort of trying to cache the username/password - * per newsgroup. It is extremely hard to make it work along with - * nntp voluntary password checking mechanism. We are backing this - * feature out. Instead of touching various of backend msg files - * at this late Dogbert 4.0 beta4 game, the infrastructure will - * remain in the msg library. We only modify codes within this file. - * Maybe one day we will try to do it again. Zzzzz -- jht - */ - - if(MK_NNTP_RESPONSE_AUTHINFO_REQUIRE == m_responseCode || - MK_NTTP_RESPONSE_AUTHINFO_SIMPLE_REQUIRE == m_responseCode || - MK_NNTP_RESPONSE_PERMISSION_DENIED == m_responseCode) - { - m_nextState = NNTP_BEGIN_AUTHORIZE; - if (MK_NNTP_RESPONSE_PERMISSION_DENIED == m_responseCode) - { - if (MK_NNTP_RESPONSE_TYPE_OK == MK_NNTP_RESPONSE_TYPE(m_previousResponseCode) - { - if (net_news_last_username_probably_valid) - net_news_last_username_probably_valid = PR_FALSE; - else - { - m_newsgroup->SetUsername(NULL); - m_newsgroup->SetPassword(NULL); - } - } - else - { - net_news_last_username_probably_valid = PR_FALSE; - if (NNTP_PASSWORD_RESPONSE == m_nextStateAfterResponse) - { - m_newsgroup->SetUsername(NULL); - m_newsgroup->SetPassword(NULL); - } - } - } - } -#else if (MK_NNTP_RESPONSE_AUTHINFO_REQUIRE == m_responseCode || MK_NNTP_RESPONSE_AUTHINFO_SIMPLE_REQUIRE == m_responseCode) { @@ -1158,17 +1150,12 @@ PRInt32 nsNNTPProtocol::NewsResponse(nsIInputStream * inputStream, PRUint32 leng } else if (MK_NNTP_RESPONSE_PERMISSION_DENIED == m_responseCode) { - net_news_last_username_probably_valid = PR_FALSE; -#ifdef UNREADY_CODE - return net_display_html_error_state(ce); -#else PR_FREEIF(line); return (0); -#endif } -#endif - else + else { m_nextState = m_nextStateAfterResponse; + } PR_FREEIF(line); return(0); /* everything ok */ @@ -1511,8 +1498,7 @@ PRInt32 nsNNTPProtocol::SendListSubscriptionsResponse(nsIInputStream * inputStre if ('.' != line[0]) { #if 0 - char *urlScheme = "news:"; - char *url = PR_smprintf ("%s//%s/%s", urlScheme, m_hostName, line); + char *url = PR_smprintf ("%s//%s/%s", NEWS_SCHEME, m_hostName, line); if (url) MSG_AddSubscribedNewsgroup (cd->pane, url); #endif @@ -2303,163 +2289,65 @@ void nsNNTPProtocol::ParseHeaderForCancel(char *buf) PRInt32 nsNNTPProtocol::BeginAuthorization() { char * command = 0; - nsXPIDLString username; + nsXPIDLCString username; nsresult rv = NS_OK; PRInt32 status = 0; - nsCOMPtr newsFolder; nsXPIDLCString cachedUsername; -#if 0 - char * cp; -#endif /* 0 */ - NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv); - if (NS_FAILED(rv)) return(MK_NNTP_AUTH_FAILED); + if (!m_newsFolder) { + if (!m_runningURL) return NS_ERROR_FAILURE; - nsCAutoString newsgroupURI; - if (m_newsgroup && m_hostName) { - nsXPIDLCString groupName; - rv = m_newsgroup->GetName(getter_Copies(groupName)); - if (NS_SUCCEEDED(rv) && groupName) { - newsgroupURI = kNewsRootURI; - newsgroupURI += "/"; - if (m_userName) { - newsgroupURI += m_userName; - newsgroupURI += "@"; - } - newsgroupURI += m_hostName; - newsgroupURI += "/"; - newsgroupURI += groupName; - } - } - -#ifdef CACHE_NEWSGRP_PASSWORD - /* reuse cached username from newsgroup folder info*/ - if (cd->pane && - (!net_news_last_username_probably_valid || - (last_username_hostname && - PL_strcasecmp(last_username_hostname, m_hostName)))) - { - m_newsgroup->GetUsername(&username); - if (username && last_username && - !PL_strcmp (username, last_username) && - (m_previousResponseCode == MK_NNTP_RESPONSE_AUTHINFO_OK || - m_previousResponseCode == MK_NNTP_RESPONSE_AUTHINFO_SIMPLE_OK || - m_previousResponseCode == MK_NNTP_RESPONSE_GROUP_SELECTED)) { - PR_FREEIF (username); - m_newsgroup->SetUsername(NULL); - m_newsgroup->SetPassword(NULL); - } - } -#endif - -#if 0 - /* Following a snews://username:password@newhost.domain.com/newsgroup.topic - * backend calls MSG_Master::FindNewsHost() to locate the folderInfo and setting - * the username/password to the newsgroup folderInfo - */ - m_newsgroup->GetUsername(&username); - if (username && *username) { - NET_SACopy(&last_username, username); - NET_SACopy(&last_username_hostname, m_hostName); - /* use it for only once */ - m_newsgroup->SetUsername(NULL); - } - else { - /* empty username; free and clear it so it will work with - * our logic - */ - PR_FREEIF(username); + nsCAutoString folderURI = "news://"; + folderURI += (const char *)m_hostName; + folderURI += "/"; + + nsXPIDLCString newsgroupName; + rv = m_runningURL->GetNewsgroupName(getter_Copies(newsgroupName)); + if (NS_SUCCEEDED(rv) && ((const char *)newsgroupName)) { + folderURI += (const char *)newsgroupName; + rv = InitializeNewsFolderFromUri((const char *)folderURI); + } } - /* If the URL/m_hostName contains @ this must be triggered - * from the bookmark. Use the embed username if we could. - */ - if ((cp = PL_strchr(m_hostName, '@')) != NULL) - { - /* in this case the username and possibly - * the password are in the URL - */ - char * colon; - *cp = '\0'; - - colon = PL_strchr(m_hostName, ':'); - if(colon) - *colon = '\0'; - - NET_SACopy(&username, m_hostName); - NET_SACopy(&last_username, m_hostName); - NET_SACopy(&last_username_hostname, cp+1); - - *cp = '@'; - - if(colon) - *colon = ':'; - } - /* reuse global saved username if we think it is - * valid - */ - if (!username && net_news_last_username_probably_valid) - { - if( last_username_hostname && - !PL_strcasecmp(last_username_hostname, m_hostName) ) - NET_SACopy(&username, last_username); - else - net_news_last_username_probably_valid = PR_FALSE; - } -#endif /* 0 */ - - if ((const char *)newsgroupURI) { - nsCOMPtr resource; - rv = rdf->GetResource((const char *)newsgroupURI, getter_AddRefs(resource)); - if (NS_FAILED(rv)) return(MK_NNTP_AUTH_FAILED); - - newsFolder = do_QueryInterface(resource, &rv); - if (NS_FAILED(rv) || !newsFolder) return(MK_NNTP_AUTH_FAILED); - - rv = newsFolder->GetGroupUsername(getter_Copies(cachedUsername)); - } + if (m_newsFolder) { + rv = m_newsFolder->GetGroupUsername(getter_Copies(cachedUsername)); + } if (NS_FAILED(rv) || !cachedUsername) { #ifdef DEBUG_NEWS printf("ask for the news username\n"); #endif /* DEBUG_NEWS */ - NS_WITH_SERVICE(nsIPrompt, dialog, kCNetSupportDialogCID, &rv); - if (NS_FAILED(rv) || !dialog) { - return(MK_NNTP_AUTH_FAILED); - } nsXPIDLString usernamePromptText; GetNewsStringByName("enterUsername", getter_Copies(usernamePromptText)); - PRBool okButtonClicked = PR_FALSE; - rv = dialog->Prompt(usernamePromptText, nsnull /* default text */, getter_Copies(username), &okButtonClicked); + if (m_newsFolder) { - if (NS_SUCCEEDED(rv) && !okButtonClicked) { + if (!m_msgWindow) { + nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); + if (mailnewsurl) { + rv = mailnewsurl->GetMsgWindow(getter_AddRefs(m_msgWindow)); + } + } + rv = m_newsFolder->GetGroupUsernameWithUI(usernamePromptText, nsnull, m_msgWindow, getter_Copies(username)); + } + else { + printf("we don't know the folder\n"); + printf("this can happen if someone gives us just an article url\n"); + return(MK_NNTP_AUTH_FAILED); + } + + if (NS_FAILED(rv)) { nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); if (mailnewsurl) mailnewsurl->SetErrorMessage(NET_ExplainErrorDetails(MK_NNTP_AUTH_FAILED, "Aborted by user")); -#if 0 - /* reset net_news_last_username_probably_valid to false */ - net_news_last_username_probably_valid = PR_FALSE; -#endif /* 0 */ + return(MK_NNTP_AUTH_FAILED); } - - if (NS_FAILED(rv) || !username) { -#if 0 - /* reset net_news_last_username_probably_valid to false */ - net_news_last_username_probably_valid = PR_FALSE; -#endif /* 0 */ - return(MK_NNTP_AUTH_FAILED); - } } // !username -#ifdef CACHE_NEWSGRP_PASSWORD - if (NS_SUCCEEDED(m_newsgroup->GetUsername(&username)) { - munged_username = XP_STRDUP (username); - m_newsgroup->SetUsername(munged_username); - PR_FreeIF(munged_username); + if (NS_FAILED(rv) || (!username && !cachedUsername)) { + return(MK_NNTP_AUTH_FAILED); } -#endif NET_SACopy(&command, "AUTHINFO user "); if (cachedUsername) { @@ -2469,14 +2357,10 @@ PRInt32 nsNNTPProtocol::BeginAuthorization() NET_SACat(&command, (const char *)cachedUsername); } else { - nsCAutoString usernameCString(username); #ifdef DEBUG_NEWS - printf("use %s as the username\n",(const char *)usernameCString); + printf("use %s as the username\n",(const char *)username); #endif /* DEBUG_NEWS */ - if (newsFolder) { - rv = newsFolder->SetGroupUsername((const char *)usernameCString); - } - NET_SACat(&command, (const char *)usernameCString); + NET_SACat(&command, (const char *)username); } NET_SACat(&command, CRLF); @@ -2497,39 +2381,8 @@ PRInt32 nsNNTPProtocol::BeginAuthorization() PRInt32 nsNNTPProtocol::AuthorizationResponse() { nsresult rv = NS_OK; - nsCOMPtr newsFolder; PRInt32 status = 0; - nsXPIDLCString cachedPassword; - NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv); - if (NS_FAILED(rv)) return(MK_NNTP_AUTH_FAILED); - - nsCAutoString newsgroupURI; - if (m_newsgroup && m_hostName) { - nsXPIDLCString groupName; - rv = m_newsgroup->GetName(getter_Copies(groupName)); - if (NS_SUCCEEDED(rv) && groupName) { - newsgroupURI = kNewsRootURI; - newsgroupURI += "/"; - if (m_userName) { - newsgroupURI += m_userName; - newsgroupURI += "@"; - } - newsgroupURI += m_hostName; - newsgroupURI += "/"; - newsgroupURI += groupName; - } - } - - if ((const char *)newsgroupURI) { - nsCOMPtr resource; - rv = rdf->GetResource((const char *)newsgroupURI, getter_AddRefs(resource)); - if (NS_FAILED(rv)) return(MK_NNTP_AUTH_FAILED); - - newsFolder = do_QueryInterface(resource, &rv); - if (NS_FAILED(rv) || !newsFolder) return(MK_NNTP_AUTH_FAILED); - rv = newsFolder->GetGroupPassword(getter_Copies(cachedPassword)); - } if (MK_NNTP_RESPONSE_AUTHINFO_OK == m_responseCode || MK_NNTP_RESPONSE_AUTHINFO_SIMPLE_OK == m_responseCode) @@ -2552,7 +2405,6 @@ PRInt32 nsNNTPProtocol::AuthorizationResponse() /* Normal authentication */ m_nextState = SEND_FIRST_NNTP_COMMAND; - net_news_last_username_probably_valid = PR_TRUE; return(0); } else if (MK_NNTP_RESPONSE_AUTHINFO_CONT == m_responseCode) @@ -2560,100 +2412,63 @@ PRInt32 nsNNTPProtocol::AuthorizationResponse() /* password required */ char * command = 0; - nsXPIDLString password; -#if 0 - char * cp; + nsXPIDLCString password; + nsXPIDLCString cachedPassword; - if (net_news_last_username_probably_valid - && last_password - && last_password_hostname - && !PL_strcasecmp(last_password_hostname, m_hostName)) - { -#ifdef CACHE_NEWSGRP_PASSWORD - if (cd->pane) - m_newsgroup->GetPassword(&password); - password = XP_STRDUP(password); -#else - NET_SACopy(&password, last_password); -#endif - } - else if ((cp = PL_strchr(m_hostName, '@')) != NULL) - { - /* in this case the username and possibly - * the password are in the URL - */ - char * colon; - *cp = '\0'; - - colon = PL_strchr(m_hostName, ':'); - if(colon) - { - *colon = '\0'; - - NET_SACopy(&password, colon+1); - NET_SACopy(&last_password, colon+1); - NET_SACopy(&last_password_hostname, cp+1); + if (!m_newsFolder) { + if (!m_runningURL) return NS_ERROR_FAILURE; - *colon = ':'; - } - - *cp = '@'; - - } -#endif /* 0 */ + nsCAutoString folderURI = "news://"; + folderURI += (const char *)m_hostName; + folderURI += "/"; - if (!cachedPassword) - { + nsXPIDLCString newsgroupName; + rv = m_runningURL->GetNewsgroupName(getter_Copies(newsgroupName)); + if (NS_SUCCEEDED(rv) && ((const char *)newsgroupName)) { + folderURI += (const char *)newsgroupName; + rv = InitializeNewsFolderFromUri((const char *)folderURI); + } + } + + if (m_newsFolder) { + rv = m_newsFolder->GetGroupPassword(getter_Copies(cachedPassword)); + } + if (NS_FAILED(rv) || !cachedPassword) { #ifdef DEBUG_NEWS printf("ask for the news password\n"); #endif /* DEBUG_NEWS */ - NS_WITH_SERVICE(nsIPrompt, dialog, kCNetSupportDialogCID, &rv); - if (NS_FAILED(rv) || !dialog) { - return(MK_NNTP_AUTH_FAILED); - } - nsXPIDLString passwordPromptText; GetNewsStringByName("enterPassword", getter_Copies(passwordPromptText)); nsXPIDLString passwordPromptTitleText; GetNewsStringByName("enterPasswordTitle", getter_Copies(passwordPromptTitleText)); - PRBool okButtonClicked = PR_FALSE; - rv = dialog->PromptPassword(passwordPromptText, passwordPromptTitleText, getter_Copies(password), &okButtonClicked); + if (m_newsFolder) { + if (!m_msgWindow) { + nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); + if (mailnewsurl) { + rv = mailnewsurl->GetMsgWindow(getter_AddRefs(m_msgWindow)); + } + } + rv = m_newsFolder->GetGroupPasswordWithUI(passwordPromptText, passwordPromptTitleText, m_msgWindow, getter_Copies(password)); + } + else { + printf("we don't know the folder\n"); + printf("this can happen if someone gives us just an article url\n"); + return(MK_NNTP_AUTH_FAILED); + } - if (NS_SUCCEEDED(rv) && !okButtonClicked) { + if (NS_FAILED(rv)) { nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); if (mailnewsurl) mailnewsurl->SetErrorMessage(NET_ExplainErrorDetails(MK_NNTP_AUTH_FAILED, "Aborted by user")); return(MK_NNTP_AUTH_FAILED); } -#if 0 - net_news_last_username_probably_valid = PR_FALSE; -#endif /* 0 */ } if(NS_FAILED(rv) || (!password && !cachedPassword)) { return(MK_NNTP_AUTH_FAILED); } -#if 0 - else - { - NET_SACopy(&last_password, password); - NET_SACopy(&last_password_hostname, m_hostName); - } -#endif /* 0 */ - -#ifdef CACHE_NEWSGRP_PASSWORD - char *garbage_password; - nsresult rv; - rv = m_newsgroup->GetPassword(&garbage_password); - if (!NS_SUCCEEDED(rv)) { - PR_Free(garbage_password); - munged_password = XP_STRDUP(password); - m_newsgroup->SetPassword(munged_password); - PR_FREEIF(munged_password); - } -#endif NET_SACopy(&command, "AUTHINFO pass "); if (cachedPassword) { @@ -2663,14 +2478,10 @@ PRInt32 nsNNTPProtocol::AuthorizationResponse() NET_SACat(&command, (const char *)cachedPassword); } else { - nsCAutoString passwordCString(password); #ifdef DEBUG_NEWS - printf("use %s as the password\n",(const char *)passwordCString); + printf("use %s as the password\n",(const char *)password); #endif /* DEBUG_NEWS */ - if (newsFolder) { - rv = newsFolder->SetGroupPassword((const char *)passwordCString); - } - NET_SACat(&command, (const char *)passwordCString); + NET_SACat(&command, (const char *)password); } NET_SACat(&command, CRLF); @@ -2694,12 +2505,6 @@ PRInt32 nsNNTPProtocol::AuthorizationResponse() MK_NNTP_AUTH_FAILED, m_responseText ? m_responseText : "")); -#ifdef CACHE_NEWSGRP_PASSWORD - if (cd->pane) - m_newsgroup->SetUsername(NULL); -#endif - net_news_last_username_probably_valid = PR_FALSE; - return(MK_NNTP_AUTH_FAILED); } @@ -2733,8 +2538,6 @@ PRInt32 nsNNTPProtocol::PasswordResponse() /* Normal authentication */ m_nextState = SEND_FIRST_NNTP_COMMAND; - net_news_last_username_probably_valid = PR_TRUE; - // if we are posting, m_newsgroup will be null if (!m_newsgroupList && m_newsgroup) { nsXPIDLCString groupName; @@ -2756,10 +2559,6 @@ PRInt32 nsNNTPProtocol::PasswordResponse() MK_NNTP_AUTH_FAILED, m_responseText ? m_responseText : "")); -#ifdef CACHE_NEWSGRP_PASSWORD - if (cd->pane) - m_newsgroup->SetPassword(NULL); -#endif return(MK_NNTP_AUTH_FAILED); } diff --git a/mailnews/news/src/nsNNTPProtocol.h b/mailnews/news/src/nsNNTPProtocol.h index 00acda0065ed..24fd54f76b7e 100644 --- a/mailnews/news/src/nsNNTPProtocol.h +++ b/mailnews/news/src/nsNNTPProtocol.h @@ -37,6 +37,8 @@ #include "nsINNTPHost.h" #include "nsINNTPNewsgroup.h" #include "nsIMsgOfflineNewsState.h" +#include "nsIMsgNewsFolder.h" +#include "nsIMsgWindow.h" #include "nsMsgLineBuffer.h" #include "nsSpecialSystemDirectory.h" @@ -146,7 +148,7 @@ class nsNNTPProtocol : public nsMsgProtocol public: // Creating a protocol instance requires the URL // need to call Initialize after we do a new of nsNNTPProtocol - nsNNTPProtocol(nsIURI * aURL); + nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow); virtual ~nsNNTPProtocol(); // initialization function given a news url @@ -185,6 +187,9 @@ private: nsCOMPtr m_newsgroup; nsCOMPtr m_offlineNewsState; + nsCOMPtr m_newsFolder; + nsCOMPtr m_msgWindow; + nsCOMPtr m_displayConsumer; nsCOMPtr mDisplayInputStream; nsCOMPtr mDisplayOutputStream; @@ -374,6 +379,7 @@ private: void SetProgressBarPercent(int percent); void SetProgressStatus(char * message); + nsresult InitializeNewsFolderFromUri(const char *uri); }; NS_BEGIN_EXTERN_C diff --git a/mailnews/news/src/nsNewsFolder.cpp b/mailnews/news/src/nsNewsFolder.cpp index ab02ec400f19..102973ca1228 100644 --- a/mailnews/news/src/nsNewsFolder.cpp +++ b/mailnews/news/src/nsNewsFolder.cpp @@ -54,6 +54,13 @@ #include "nsMsgBaseCID.h" #include "nsFileStream.h" +#include "nsIMsgWindow.h" +#include "nsIWebShell.h" +#include "nsIWebShellWindow.h" +#include "nsINetPrompt.h" + +#include "nsXPIDLString.h" + // we need this because of an egcs 1.0 (and possibly gcc) compiler bug // that doesn't allow you to call ::nsISupports::GetIID() inside of a class // that multiply inherits from nsISupports @@ -70,6 +77,9 @@ static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); #define NEWSGROUP_PASSWORD_PREF_PREFIX "newsgroup.password." #define NEWSRC_FILE_BUFFER_SIZE 1024 +#define NEWS_SCHEME "news:" +#define SNEWS_SCHEME "snews:" + //////////////////////////////////////////////////////////////////////////////// @@ -123,10 +133,6 @@ nsMsgNewsFolder::CreateSubFolders(nsFileSpec &path) { nsresult rv = NS_OK; - char *hostname; - rv = GetHostname(&hostname); - if (NS_FAILED(rv)) return rv; - PRBool isNewsServer = PR_FALSE; rv = GetIsServer(&isNewsServer); if (NS_FAILED(rv)) return rv; @@ -158,8 +164,6 @@ nsMsgNewsFolder::CreateSubFolders(nsFileSpec &path) rv = NS_OK; } - PR_FREEIF(hostname); - return rv; } @@ -167,12 +171,11 @@ NS_IMETHODIMP nsMsgNewsFolder::AddNewsgroup(const char *name, const char *setStr, nsIMsgFolder **child) { if (!child) return NS_ERROR_NULL_POINTER; - - if (!setStr) return NS_ERROR_NULL_POINTER; + if (!setStr) return NS_ERROR_NULL_POINTER; + if (!name) return NS_ERROR_NULL_POINTER; #ifdef DEBUG_NEWS - nsCString nameStr(name); - printf("AddNewsgroup(%s,??,%s)\n",nameStr.GetBuffer(),setStr); + printf("AddNewsgroup(%s,??,%s)\n",name,setStr); #endif nsresult rv = NS_OK; @@ -443,8 +446,6 @@ nsMsgNewsFolder::GetMessages(nsIMsgWindow *aMsgWindow, nsISimpleEnumerator* *res NS_IMETHODIMP nsMsgNewsFolder::GetFolderURL(char **url) { - const char *urlScheme = "news:"; - if(!url) return NS_ERROR_NULL_POINTER; @@ -457,10 +458,10 @@ NS_IMETHODIMP nsMsgNewsFolder::GetFolderURL(char **url) if (NS_FAILED(rv)) return rv; #if defined(XP_MAC) nsCAutoString tmpPath((nsFilePath)path); //ducarroz: please don't cast a nsFilePath to char* on Mac - *url = PR_smprintf("%s%s", urlScheme, tmpPath.GetBuffer()); + *url = PR_smprintf("%s%s", NEWS_SCHEME, tmpPath.GetBuffer()); #else const char *pathName = path; - *url = PR_smprintf("%s%s", urlScheme, pathName); + *url = PR_smprintf("%s%s", NEWS_SCHEME, pathName); #endif return NS_OK; @@ -774,7 +775,7 @@ NS_IMETHODIMP nsMsgNewsFolder::GetSizeOnDisk(PRUint32 *size) /* this is news, so remember that DeleteMessage is really CANCEL */ NS_IMETHODIMP nsMsgNewsFolder::DeleteMessages(nsISupportsArray *messages, - nsIMsgWindow *msgWindow, PRBool deleteStorage) + nsIMsgWindow *aMsgWindow, PRBool deleteStorage) { nsresult rv = NS_OK; @@ -786,21 +787,18 @@ NS_IMETHODIMP nsMsgNewsFolder::DeleteMessages(nsISupportsArray *messages, NS_WITH_SERVICE(nsINntpService, nntpService, kNntpServiceCID, &rv); if (NS_SUCCEEDED(rv) && nntpService) { - char *hostname = nsnull; - rv = GetHostname(&hostname); + nsXPIDLCString hostname; + rv = GetHostname(getter_Copies(hostname)); if (NS_FAILED(rv)) return rv; - PRUnichar *newsgroupname = nsnull; - rv = GetName(&newsgroupname); - nsCString asciiName(newsgroupname); + nsXPIDLString newsgroupname; + rv = GetName(getter_Copies(newsgroupname)); + nsCAutoString asciiName(newsgroupname); if (NS_FAILED(rv)) { - PR_FREEIF(hostname); return rv; } - rv = nntpService->CancelMessages(hostname, asciiName.GetBuffer(), messages, nsnull /* consumer */, nsnull, nsnull); - - PR_FREEIF(hostname); - PR_FREEIF(newsgroupname); + rv = nntpService->CancelMessages((const char *)hostname, (const char *)asciiName, messages, nsnull /* consumer */, nsnull, aMsgWindow, nsnull); + } return rv; @@ -1154,134 +1152,202 @@ NS_IMETHODIMP nsMsgNewsFolder::SetUnreadSetStr(const char * aUnreadSetStr) NS_IMETHODIMP nsMsgNewsFolder::GetGroupUsername(char **aGroupUsername) { - nsresult rv = NS_OK; - - if (!aGroupUsername) return NS_ERROR_NULL_POINTER; - - if (!mGroupUsername) { - nsCAutoString prefName = NEWSGROUP_USERNAME_PREF_PREFIX; - prefName += mURI; - rv = GetRememberedPref((const char *)prefName, &mGroupUsername); - } - - if (NS_SUCCEEDED(rv) && mGroupUsername) { + NS_ENSURE_ARG_POINTER(aGroupUsername); + nsresult rv; +#ifdef DEBUG_sspitzer + printf("get the group username for %s\n",mURI); +#endif + if (mGroupUsername) { *aGroupUsername = PL_strdup(mGroupUsername); - if (!*aGroupUsername) return NS_ERROR_FAILURE; rv = NS_OK; } + else { + rv = NS_ERROR_FAILURE; + } return rv; } NS_IMETHODIMP nsMsgNewsFolder::SetGroupUsername(const char *aGroupUsername) { - nsresult rv; + NS_ENSURE_ARG_POINTER(aGroupUsername); - if (!aGroupUsername) return NS_ERROR_INVALID_ARG; PR_FREEIF(mGroupUsername); mGroupUsername = PL_strdup(aGroupUsername); - if (!mGroupUsername) return NS_ERROR_FAILURE; - nsCAutoString prefName = NEWSGROUP_USERNAME_PREF_PREFIX; - prefName += mURI; - - rv = SetRememberedPref((const char *)prefName, mGroupUsername); - return rv; + return NS_OK; } NS_IMETHODIMP nsMsgNewsFolder::GetGroupPassword(char **aGroupPassword) { - nsresult rv = NS_OK; - if (!aGroupPassword) return NS_ERROR_NULL_POINTER; + NS_ENSURE_ARG_POINTER(aGroupPassword); + nsresult rv; - if (!mGroupPassword) { - nsCAutoString prefName = NEWSGROUP_PASSWORD_PREF_PREFIX; - prefName += mURI; - rv = GetRememberedPref((const char *)prefName, &mGroupPassword); - } - - if (NS_SUCCEEDED(rv) && mGroupPassword) { + if (mGroupPassword) { *aGroupPassword = PL_strdup(mGroupPassword); - if (!*aGroupPassword) return NS_ERROR_FAILURE; - rv = NS_OK; + rv = NS_OK; + } + else { + rv = NS_ERROR_FAILURE; } - return rv; + return rv; } NS_IMETHODIMP nsMsgNewsFolder::SetGroupPassword(const char *aGroupPassword) { - nsresult rv; + NS_ENSURE_ARG_POINTER(aGroupPassword); - if (!aGroupPassword) return NS_ERROR_INVALID_ARG; - PR_FREEIF(mGroupPassword); + PR_FREEIF(mGroupPassword); - mGroupPassword = PL_strdup(aGroupPassword); - if (!mGroupPassword) return NS_ERROR_FAILURE; + mGroupPassword = PL_strdup(aGroupPassword); - nsCAutoString prefName = NEWSGROUP_PASSWORD_PREF_PREFIX; - prefName += mURI; - - rv = SetRememberedPref((const char *)prefName, mGroupPassword); - return rv; + return NS_OK; } -nsresult nsMsgNewsFolder::GetRememberedPref(const char *prefName, char **prefValue) +NS_IMETHODIMP +nsMsgNewsFolder::GetGroupPasswordWithUI(const PRUnichar * aPromptMessage, const + PRUnichar *aPromptTitle, + nsIMsgWindow* aMsgWindow, + char **aGroupPassword) { - PRBool rememberPassword; - nsresult rv; + nsresult rv = NS_OK; - nsCOMPtr server; - rv = GetServer(getter_AddRefs(server)); - if (NS_FAILED(rv)) return rv; +#ifdef DEBUG_sspitzer + printf("with ui, get the group username for %s\n",mURI); +#endif - rv = server->GetRememberPassword(&rememberPassword); - if (NS_FAILED(rv)) return rv; + NS_ENSURE_ARG_POINTER(aMsgWindow); + NS_ENSURE_ARG_POINTER(aGroupPassword); - if (!rememberPassword) { - // we weren't supposed to have remembered anything - *prefValue = nsnull; - return NS_OK; - } + if (!mGroupPassword) { + // prompt the user for the password + nsCOMPtr webShell; + rv = aMsgWindow->GetRootWebShell(getter_AddRefs(webShell)); + if (NS_FAILED(rv)) return rv; + // get top level window + nsCOMPtr topLevelWindow; + rv = webShell->GetTopLevelWindow(getter_AddRefs(topLevelWindow)); + if (NS_FAILED(rv)) return rv; + nsCOMPtr dialog( do_QueryInterface( topLevelWindow, &rv ) ); + if (NS_SUCCEEDED(rv)) + { + nsXPIDLString uniGroupPassword; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_FAILED(rv)) return rv; + PRBool okayValue = PR_TRUE; + + nsCAutoString signonURI(mURI); +#if SINGLE_SIGNON_USING_FULL_URLS + signonURI += "#password"; +#else + signonURI = NEWS_SCHEME; + signonURI += "//"; + nsXPIDLCString hostname; + rv = GetHostname(getter_Copies(hostname)); + if (NS_FAILED(rv)) return rv; - rv = prefs->CopyCharPref(prefName, prefValue); -#ifdef DEBUG_NEWS - if (NS_SUCCEEDED(rv)) { - printf("getting %s as %s\n",prefName, prefValue); - } -#endif /* DEBUG_NEWS */ + signonURI += (const char *)hostname; + signonURI += "-"; + + nsXPIDLString newsgroupname; + rv = GetName(getter_Copies(newsgroupname)); + if (NS_FAILED(rv)) return rv; + + nsCAutoString asciiName(newsgroupname); + + signonURI += (const char *)asciiName; + signonURI += "-password"; +#endif + + rv = dialog->PromptPassword((const char *)signonURI, aPromptTitle, aPromptMessage, getter_Copies(uniGroupPassword), &okayValue); + if (NS_FAILED(rv)) return rv; + + if (!okayValue) // if the user pressed cancel, just return NULL; + { + *aGroupPassword = nsnull; + return rv; + } + + // we got a password back...so remember it + nsCString aCStr(uniGroupPassword); + rv = SetGroupPassword((const char *) aCStr); + if (NS_FAILED(rv)) return rv; + + } // if we got a prompt dialog + } // if the password is empty + + rv = GetGroupPassword(aGroupPassword); return rv; } -nsresult nsMsgNewsFolder::SetRememberedPref(const char *prefName, const char *prefValue) +NS_IMETHODIMP +nsMsgNewsFolder::GetGroupUsernameWithUI(const PRUnichar * aPromptMessage, const + PRUnichar *aPromptTitle, + nsIMsgWindow* aMsgWindow, + char **aGroupUsername) { - PRBool rememberPassword; - nsresult rv; + nsresult rv = NS_OK; - nsCOMPtr server; - rv = GetServer(getter_AddRefs(server)); - if (NS_FAILED(rv)) return rv; + NS_ENSURE_ARG_POINTER(aMsgWindow); + NS_ENSURE_ARG_POINTER(aGroupUsername); - rv = server->GetRememberPassword(&rememberPassword); - if (NS_FAILED(rv)) return rv; + if (!mGroupUsername) { + // prompt the user for the password + nsCOMPtr webShell; + rv = aMsgWindow->GetRootWebShell(getter_AddRefs(webShell)); + if (NS_FAILED(rv)) return rv; + // get top level window + nsCOMPtr topLevelWindow; + rv = webShell->GetTopLevelWindow(getter_AddRefs(topLevelWindow)); + if (NS_FAILED(rv)) return rv; + nsCOMPtr dialog( do_QueryInterface( topLevelWindow, &rv ) ); + if (NS_SUCCEEDED(rv)) + { + nsXPIDLString uniGroupUsername; - if (!rememberPassword) { - // we aren't supposed to remember this - return NS_OK; - } + PRBool okayValue = PR_TRUE; - NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv); - if (NS_FAILED(rv)) return rv; + nsCAutoString signonURI(mURI); +#if SINGLE_SIGNON_USING_FULL_URLS + signonURI += "#username"; +#else + signonURI = NEWS_SCHEME; + signonURI += "//"; + nsXPIDLCString hostname; + rv = GetHostname(getter_Copies(hostname)); + if (NS_FAILED(rv)) return rv; - rv = prefs->SetCharPref(prefName, prefValue); -#ifdef DEBUG_NEWS - if (NS_SUCCEEDED(rv)) { - printf("setting %s as %s\n",prefName, prefValue); - } -#endif /* DEBUG_NEWS */ - return rv; + signonURI += (const char *)hostname; + signonURI += "-"; + + nsXPIDLString newsgroupname; + rv = GetName(getter_Copies(newsgroupname)); + if (NS_FAILED(rv)) return rv; + + nsCAutoString asciiName(newsgroupname); + + signonURI += (const char *)asciiName; + signonURI += "-username"; +#endif + rv = dialog->Prompt((const char *)signonURI, aPromptTitle, aPromptMessage, getter_Copies(uniGroupUsername), &okayValue); + if (NS_FAILED(rv)) return rv; + + if (!okayValue) // if the user pressed cancel, just return NULL; + { + *aGroupUsername= nsnull; + return rv; + } + + // we got a username back, remember it + nsCString aCStr(uniGroupUsername); + rv = SetGroupUsername((const char *) aCStr); + if (NS_FAILED(rv)) return rv; + + } // if we got a prompt dialog + } // if the password is empty + + rv = GetGroupUsername(aGroupUsername); + return rv; } + diff --git a/mailnews/news/src/nsNewsFolder.h b/mailnews/news/src/nsNewsFolder.h index 114aaa296c3f..ebe436c24bcb 100644 --- a/mailnews/news/src/nsNewsFolder.h +++ b/mailnews/news/src/nsNewsFolder.h @@ -124,10 +124,6 @@ protected: // used for auth news char *mGroupUsername; char *mGroupPassword; - -private: - nsresult SetRememberedPref(const char *prefName, const char *prefValue); - nsresult GetRememberedPref(const char *prefName, char **prefValue); }; #endif // nsMsgNewsFolder_h__ diff --git a/mailnews/news/src/nsNntpService.cpp b/mailnews/news/src/nsNntpService.cpp index b65c2a516a78..a9f1e6d19b07 100644 --- a/mailnews/news/src/nsNntpService.cpp +++ b/mailnews/news/src/nsNntpService.cpp @@ -129,7 +129,7 @@ nsNntpService::SaveMessageToDisk(const char *aMessageURI, msgUrl->SetCanonicalLineEnding(canonicalLineEnding); } - RunNewsUrl(myuri, nsnull); + RunNewsUrl(myuri, nsnull, nsnull); } if (aURL) @@ -181,7 +181,7 @@ nsresult nsNntpService::DisplayMessage(const char* aMessageURI, nsISupports * aD if (NS_SUCCEEDED(rv) && webshell) rv = webshell->LoadURI(myuri, "view", nsnull, PR_TRUE); else - rv = RunNewsUrl(myuri, aDisplayConsumer); + rv = RunNewsUrl(myuri, aMsgWindow, aDisplayConsumer); } if (aURL) @@ -429,10 +429,11 @@ nsresult nsNntpService::FindHostFromGroup(nsCString &host, nsCString &groupName) } nsresult -nsNntpService::DetermineHostForPosting(nsCString &host, const char *newsgroupsNames) +nsNntpService::SetUpNntpUrlForPosting(nsINntpUrl *nntpUrl, const char *newsgroupsNames) { nsresult rv = NS_OK; - + nsCAutoString host; + if (!newsgroupsNames) return NS_ERROR_NULL_POINTER; if (PL_strlen(newsgroupsNames) == 0) return NS_ERROR_FAILURE; @@ -459,7 +460,9 @@ nsNntpService::DetermineHostForPosting(nsCString &host, const char *newsgroupsNa char *token = nsnull; char *rest = list; nsCAutoString str; - + PRUint32 numGroups = 0; // the number of newsgroup we are attempt to post to + nsCAutoString currentGroup; + token = nsCRT::strtok(rest, ",", &rest); while (token && *token) { str = token; @@ -498,6 +501,7 @@ nsNntpService::DetermineHostForPosting(nsCString &host, const char *newsgroupsNa if (slashpos > 0 ) { // theRest is "host/group" theRest.Left(currentHost, slashpos); + theRest.Right(currentGroup, slashpos); #ifdef DEBUG_NEWS printf("currentHost == %s\n", currentHost.GetBuffer()); #endif @@ -505,12 +509,14 @@ nsNntpService::DetermineHostForPosting(nsCString &host, const char *newsgroupsNa else { // theRest is "group" rv = FindHostFromGroup(currentHost, str); + currentGroup = str; if (NS_FAILED(rv)) { PR_FREEIF(list); return rv; } } + numGroups++; if (host.IsEmpty()) { host = currentHost; @@ -519,7 +525,7 @@ nsNntpService::DetermineHostForPosting(nsCString &host, const char *newsgroupsNa } else { if (host != currentHost) { - printf("no cross posting to multiple hosts!\n"); + printf("todo, implement an alert: no cross posting to multiple hosts!\n"); PR_FREEIF(list); return NS_ERROR_FAILURE; } @@ -537,10 +543,32 @@ nsNntpService::DetermineHostForPosting(nsCString &host, const char *newsgroupsNa } PR_FREEIF(list); - if (!host.IsEmpty()) - return NS_OK; - else + if (host.IsEmpty()) return NS_ERROR_FAILURE; + + nsCAutoString urlStr = kNewsRootURI; + urlStr += "/"; + urlStr += (const char *)host; + + // if the user tried to post to one newsgroup, set that information in the + // nntp url. this can save them an authentication, if they've already logged in + // and we have that information in the single signon database + if ((numGroups == 1) && ((const char *)currentGroup)) { + rv = nntpUrl->SetNewsgroupName((const char *)currentGroup); + if (NS_FAILED(rv)) return rv; + } + + nsCOMPtr mailnewsurl = do_QueryInterface(nntpUrl); + + if (mailnewsurl) { + mailnewsurl->SetSpec((const char *)urlStr); + mailnewsurl->SetPort(NEWS_PORT); + } + else { + return NS_ERROR_FAILURE; + } + + return NS_OK; } //////////////////////////////////////////////////////////////////////////////////////// // nsINntpService support @@ -712,32 +740,19 @@ nsresult nsNntpService::PostMessage(nsIFileSpec *fileToPost, const char *newsgro nntpUrl->SetNewsAction(nsINntpUrl::ActionPostArticle); - nsCAutoString host; - rv = DetermineHostForPosting(host, newsgroupsNames); - - if (NS_FAILED(rv) || (host.IsEmpty())) return rv; + rv = SetUpNntpUrlForPosting(nntpUrl, newsgroupsNames); + if (NS_FAILED(rv)) return rv; - printf("post to this host: %s\n",host.GetBuffer()); - - char *urlstr = PR_smprintf("%s/%s",kNewsRootURI,host.GetBuffer()); nsCOMPtr mailnewsurl = do_QueryInterface(nntpUrl); - if (mailnewsurl) { - mailnewsurl->SetSpec(urlstr); - mailnewsurl->SetPort(NEWS_PORT); - } - else { - return NS_ERROR_FAILURE; - } - - PR_FREEIF(urlstr); - + if (!mailnewsurl) return NS_ERROR_FAILURE; + if (aUrlListener) // register listener if there is one... mailnewsurl->RegisterListener(aUrlListener); // almost there...now create a nntp protocol instance to run the url in... nsNNTPProtocol *nntpProtocol = nsnull; - nntpProtocol = new nsNNTPProtocol(mailnewsurl); + nntpProtocol = new nsNNTPProtocol(mailnewsurl, nsnull); if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY;; rv = nntpProtocol->Initialize(); @@ -807,15 +822,17 @@ nsresult nsNntpService::ConstructNntpUrl(const char * urlString, const char * ne } nsresult -nsNntpService::RunNewsUrl(nsIURI * aUri, nsISupports * aConsumer) +nsNntpService::RunNewsUrl(nsIURI * aUri, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer) { + nsresult rv; + // almost there...now create a nntp protocol instance to run the url in... nsNNTPProtocol *nntpProtocol = nsnull; - nntpProtocol = new nsNNTPProtocol(aUri); + nntpProtocol = new nsNNTPProtocol(aUri, aMsgWindow); if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = nntpProtocol->Initialize(); + rv = nntpProtocol->Initialize(); if (NS_FAILED(rv)) return rv; rv = nntpProtocol->LoadUrl(aUri, aConsumer); @@ -891,7 +908,7 @@ NS_IMETHODIMP nsNntpService::GetNewNews(nsINntpIncomingServer *nntpServer, const mailNewsUrl->SetMsgWindow(aMsgWindow); } - rv = RunNewsUrl(aUrl, nsnull); + rv = RunNewsUrl(aUrl, aMsgWindow, nsnull); if (_retval) { @@ -907,7 +924,7 @@ NS_IMETHODIMP nsNntpService::GetNewNews(nsINntpIncomingServer *nntpServer, const return rv; } -NS_IMETHODIMP nsNntpService::CancelMessages(const char *hostname, const char *newsgroupname, nsISupportsArray *messages, nsISupports * aConsumer, nsIUrlListener * aUrlListener, nsIURI ** aURL) +NS_IMETHODIMP nsNntpService::CancelMessages(const char *hostname, const char *newsgroupname, nsISupportsArray *messages, nsISupports * aConsumer, nsIUrlListener * aUrlListener, nsIMsgWindow *aMsgWindow, nsIURI ** aURL) { nsresult rv = NS_OK; PRUint32 count = 0; @@ -975,7 +992,7 @@ NS_IMETHODIMP nsNntpService::CancelMessages(const char *hostname, const char *ne nsCOMPtr nntpUrl = do_QueryInterface(url); if (nntpUrl) nntpUrl->SetNewsAction(nsINntpUrl::ActionCancelArticle); - rv = RunNewsUrl(url, aConsumer); + rv = RunNewsUrl(url, aMsgWindow, aConsumer); if (aURL) { @@ -1034,7 +1051,7 @@ NS_IMETHODIMP nsNntpService::NewChannel(const char *verb, nsIChannel **_retval) { nsresult rv = NS_OK; - nsNNTPProtocol *nntpProtocol = new nsNNTPProtocol(aURI); + nsNNTPProtocol *nntpProtocol = new nsNNTPProtocol(aURI, nsnull); if (!nntpProtocol) return NS_ERROR_OUT_OF_MEMORY; rv = nntpProtocol->Initialize(); diff --git a/mailnews/news/src/nsNntpService.h b/mailnews/news/src/nsNntpService.h index a4a92091eb98..f05c54ceed53 100644 --- a/mailnews/news/src/nsNntpService.h +++ b/mailnews/news/src/nsNntpService.h @@ -30,6 +30,8 @@ #include "nsIFileSpec.h" #include "MailNewsTypes.h" #include "nsIMsgProtocolInfo.h" +#include "nsIMsgWindow.h" +#include "nsINntpUrl.h" class nsIURI; class nsIUrlListener; @@ -56,14 +58,14 @@ protected: nsCString &newsgroupName, nsMsgKey *aKey); - nsresult DetermineHostForPosting(nsCString &host, const char *newsgroupNames); + nsresult SetUpNntpUrlForPosting(nsINntpUrl * nntpUrl, const char *newsgroupNames); nsresult FindHostFromGroup(nsCString &host, nsCString &groupName); void FindServerWithNewsgroup(nsCString &host, nsCString &groupName); // a convience routine used to put together news urls. nsresult ConstructNntpUrl(const char * urlString, const char * newsgroupName, nsMsgKey key, nsIUrlListener *aUrlListener, nsIURI ** aUrl); // a convience routine to run news urls - nsresult RunNewsUrl (nsIURI * aUrl, nsISupports * aConsumer); + nsresult RunNewsUrl (nsIURI * aUrl, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer); static PRBool findNewsServerWithGroup(nsISupports *aElement, void *data); };