changes to get more sophisticated newsgroup addressing to work. thanks to rhp for the backend work. also checking in some xul / js to test this.

This commit is contained in:
sspitzer%netscape.com 1999-06-29 05:04:17 +00:00
parent 0872db7da4
commit 3575210d93
9 changed files with 270 additions and 51 deletions

View File

@ -123,12 +123,16 @@ nsresult nsMsgCompFields::SetHeader(PRInt32 header, const char *value, PRInt32 *
/* Since colon is not a legal character in a newsgroup name under son-of-1036
we're assuming that such a header contains a URL, and we should parse it out
to infer the news server. */
if (value && MSG_NEWSGROUPS_HEADER_MASK == header && PL_strchr(value, ':')) {
// RICHIE - for now we are not restricting this to a single mail host...// if (value && MSG_NEWSGROUPS_HEADER_MASK == header && PL_strchr(value, ':'))
if (PR_FALSE)
{
status = ParseNewsgroupsForUrls (value);
if (status == 0)
return status; /* it was a news URL, and we snarfed it up */
else {
if (status == MK_MSG_CANT_POST_TO_MULTIPLE_NEWS_HOSTS) {
else
{
if (status == MK_MSG_CANT_POST_TO_MULTIPLE_NEWS_HOSTS)
{
#ifdef UNREAD_CODE
MSG_Pane *owner = GetOwner();
if (owner)
@ -524,10 +528,12 @@ PRInt16 nsMsgCompFields::ParseNewsgroupsForUrls (const char *value)
{
int status = 0;
/* Here we pull apart the comma-separated header value and look for news
URLs. We'll use the URL to set the newspost URL to determine the host */
#if 0 //JFD
msg_StringArray values (PR_TRUE /*owns memory for strings*/);
//
// Here we pull apart the comma-separated header value and look for news
// URLs. We'll use the URL to set the newspost URL to determine the host
//
#if 0 // RICHIE - this will change with seth's new approach
msg_StringArray values (PR_TRUE /* owns memory for strings */);
values.ImportTokenList (value);
for (int i = 0; i < values.GetSize() && status == 0; i++) {
@ -557,8 +563,9 @@ PRInt16 nsMsgCompFields::ParseNewsgroupsForUrls (const char *value)
PR_Free(newValue);
}
}
#endif //JFD
return status;
#endif
return status;
}
nsresult nsMsgCompFields::SetBody(const char *value, PRInt32 *_retval)

View File

@ -27,11 +27,14 @@
#include "nsMsgCompPrefs.h"
#include "nsIMsgHeaderParser.h"
#include "nsIMimeURLUtils.h"
#include "nsINntpService.h"
#include "nsMsgNewsCID.h"
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kNetServiceCID, NS_NETSERVICE_CID);
static NS_DEFINE_CID(kMsgHeaderParserCID, NS_MSGHEADERPARSER_CID);
static NS_DEFINE_CID(kMimeURLUtilsCID, NS_IMIME_URLUTILS_CID);
static NS_DEFINE_CID(kNntpServiceCID, NS_NNTPSERVICE_CID);
//
// Hopefully, someone will write and XP call like this eventually!
@ -235,6 +238,9 @@ nsMsgStripLine (char * string)
return string;
}
//
// Generate the message headers for the new RFC822 message
//
char *
mime_generate_headers (nsMsgCompFields *fields,
const char *charset,
@ -620,8 +626,48 @@ mime_generate_headers (nsMsgCompFields *fields,
PL_strcpy(ptr+1, ptr2);
}
PUSH_STRING ("Newsgroups: ");
PUSH_STRING (n2);
// RICHIE-SHERRY: This is where I will need to make some changes for Seth's
// new feature to allow for full specification of news hosts.
//
if (deliver_mode == nsMsgDeliverNow)
{
// This is going out now...so we need to run this header through the
// call to parse it into just the group names and put that into the
// outgoing message.
char *newHeader = nsnull;
NS_WITH_SERVICE(nsINntpService, nntpService, kNntpServiceCID, &rv);
if (NS_SUCCEEDED(rv) && nntpService) {
// caller frees the memory in newHeader
// ConvertNewsgroupsString takes "news://news.mozilla.org./netscape.test,news://news.mozilla.org./netscape.junk"
// and turns it into "netscape.test,netscape.junk"
rv = nntpService->ConvertNewsgroupsString(n2, &newHeader);
if (NS_FAILED(rv)) {
printf("FAILURE to convert!\n");
printf("rhp, we need to figure out how to handle this\n");
}
else {
printf("SUCCESS: %s -> %s\n",n2,newHeader);
}
}
else {
printf("FAILURE to get nntpService\n");
printf("rhp, we need to figure out how to handle this\n");
}
PUSH_STRING ("Newsgroups: ");
PUSH_STRING (newHeader);
PR_FREEIF(newHeader);
}
else
{
// This is going to be saved for later, that means we should just store
// what the user typed into the "Newsgroup" line in the HEADER_X_MOZILLA_NEWSHOST
// header for later use by "Send Unsent Messages", "Drafts" or "Templates"
PUSH_STRING (HEADER_X_MOZILLA_NEWSHOST);
PUSH_STRING (": ");
PUSH_STRING(n2);
}
PR_Free (n2);
PUSH_NEWLINE ();
}

View File

@ -16,6 +16,7 @@
* Reserved.
*/
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "msgCore.h"
#include "rosetta_mailnews.h"
#include "nsMsgLocalFolderHdrs.h"
@ -1267,7 +1268,7 @@ nsMsgComposeAndSend::Init(
char *newb = (char *) PR_Malloc (attachment1_body_length + 1);
if (! newb)
return MK_OUT_OF_MEMORY;
memcpy (newb, attachment1_body, attachment1_body_length);
nsCRT::memcpy (newb, attachment1_body, attachment1_body_length);
newb [attachment1_body_length] = 0;
m_attachment1_body = newb;
m_attachment1_body_length = attachment1_body_length;

View File

@ -460,8 +460,11 @@ nsCOMPtr<nsIMsgSend> pMsgSend = nsnull;
if (m_newsgroups)
compFields->SetNewsgroups(m_newsgroups, NULL);
// Need to set this before calling SendMessageFile????
// m_newshost
// If we have this, we found a HEADER_X_MOZILLA_NEWSHOST which means
// that we saved what the user typed into the "Newsgroup" line in this
// header
if (m_newshost)
compFields->SetNewsgroups(m_newshost, NULL);
// Create the listener for the send operation...
mSendListener = new SendOperationListener();
@ -747,25 +750,25 @@ nsMsgSendLater::BuildHeaders()
if (!PL_strncasecmp ("BCC", buf, end - buf))
{
header = &m_bcc;
prune_p = TRUE;
prune_p = PR_TRUE;
}
break;
case 'C': case 'c':
if (!PL_strncasecmp ("CC", buf, end - buf))
header = &m_to;
else if (!PL_strncasecmp (HEADER_CONTENT_LENGTH, buf, end - buf))
prune_p = TRUE;
prune_p = PR_TRUE;
break;
case 'F': case 'f':
if (!PL_strncasecmp ("FCC", buf, end - buf))
{
header = &m_fcc;
prune_p = TRUE;
prune_p = PR_TRUE;
}
break;
case 'L': case 'l':
if (!PL_strncasecmp ("Lines", buf, end - buf))
prune_p = TRUE;
prune_p = PR_TRUE;
break;
case 'N': case 'n':
if (!PL_strncasecmp ("Newsgroups", buf, end - buf))
@ -773,7 +776,7 @@ nsMsgSendLater::BuildHeaders()
break;
case 'S': case 's':
if (!PL_strncasecmp ("Sender", buf, end - buf))
prune_p = TRUE;
prune_p = PR_TRUE;
break;
case 'T': case 't':
if (!PL_strncasecmp ("To", buf, end - buf))
@ -784,15 +787,15 @@ nsMsgSendLater::BuildHeaders()
PRInt32 headLen = PL_strlen(HEADER_X_MOZILLA_STATUS2);
if (headLen == end - buf &&
!PL_strncasecmp(HEADER_X_MOZILLA_STATUS2, buf, end - buf))
prune_p = TRUE;
prune_p = PR_TRUE;
else if (headLen == end - buf &&
!PL_strncasecmp(HEADER_X_MOZILLA_STATUS, buf, end - buf))
prune_p = do_flags_p = TRUE;
prune_p = do_flags_p = PR_TRUE;
else if (!PL_strncasecmp(HEADER_X_MOZILLA_DRAFT_INFO, buf, end - buf))
prune_p = do_return_receipt_p = TRUE;
prune_p = do_return_receipt_p = PR_TRUE;
else if (!PL_strncasecmp(HEADER_X_MOZILLA_NEWSHOST, buf, end - buf))
{
prune_p = TRUE;
prune_p = PR_TRUE;
header = &m_newshost;
}
break;

View File

@ -65,6 +65,7 @@ mailnews/news/public/Makefile
mailnews/news/src/Makefile
mailnews/news/build/Makefile
mailnews/news/resources/Makefile
mailnews/news/resources/content/Makefile
mailnews/news/resources/skin/Makefile
mailnews/news/tests/Makefile
mailnews/news/tests/nntp/Makefile

View File

@ -37,6 +37,8 @@ typedef unsigned long nsMsgKey;
[scriptable, uuid(4C9F90E0-E19B-11d2-806E-006008128C4E)]
interface nsINntpService : nsISupports {
string ConvertNewsgroupsString(in string newsgroupsStr);
nsIURI PostMessage (in nsFilePath pathToFile, in string newsgroupNames, in nsIUrlListener aUrlListener);

View File

@ -22,7 +22,7 @@ srcdir = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = skin
DIRS=content skin
include $(topsrcdir)/config/config.mk

View File

@ -61,7 +61,7 @@
#define PREF_NETWORK_HOSTS_NNTP_SERVER "network.hosts.nntp_server"
#if defined(DEBUG_sspitzer) || defined (DEBUG_seth)
#if defined(DEBUG_sspitzer_) || defined (DEBUG_seth_)
#define DEBUG_NEWS 1
#endif
@ -273,9 +273,15 @@ nsresult nsNntpService::CopyMessage(const char * aSrcMailboxURI, nsIStreamListen
nsresult nsNntpService::FindHostFromGroup(nsString &host, nsString &groupName)
{
nsresult rv = NS_OK;
// host always comes in as ""
NS_ASSERTION(host == "", "host is not empty");
if (host != "") return NS_ERROR_FAILURE;
if (0) {
// we have "group"
// todo: look for "group" in the newsrc files of all the hosts, starting with the default nntp host.
// groupName is "foobar"
// todo: look for "foobar" in the newsrc files of all the hosts,
// starting with the default nntp host.
//
// for now, leave host blank so we'll just use the default nntp host.
}
@ -302,37 +308,37 @@ nsresult nsNntpService::FindHostFromGroup(nsString &host, nsString &groupName)
return NS_OK;
}
nsresult nsNntpService::DetermineHostForPosting(nsString &host, const char *newsgroupNames)
nsresult nsNntpService::DetermineHostForPosting(nsString &host, const char *newsgroupsNames)
{
nsresult rv = NS_OK;
if (!newsgroupNames) return NS_ERROR_NULL_POINTER;
if (PL_strlen(newsgroupNames) == 0) return NS_ERROR_FAILURE;
if (!newsgroupsNames) return NS_ERROR_NULL_POINTER;
if (PL_strlen(newsgroupsNames) == 0) return NS_ERROR_FAILURE;
#ifdef DEBUG_NEWS
printf("newsgroupNames == %s\n",newsgroupNames);
printf("newsgroupsNames == %s\n",newsgroupsNames);
#endif
// newsgroupNames can be a comma seperated list of these:
// newsgroupsNames can be a comma seperated list of these:
// news://host/group
// news://group
// host/group
// group
//
// we are not going to allow the user to cross post to multiple hosts.
// so as soon as we determine the host from newsgroupNames, we can stop.
// so as soon as we determine the host from newsgroupsNames, we can stop.
//
// 1) explict (news://host/group or host/group)
// 2) context (if you reply to a message when reading it on host x, reply to that host.
// 3) no context look up news://group or group in the various newsrc files to determine host, with PREF_NETWORK_HOSTS_NNTP_SERVER being the first newrc file searched each time
// 4) use the default nntp server
//nsCRT::strtok is going destroy what we pass to it, so we need to make a copy of newsgroupNames.
char *list = PL_strdup(newsgroupNames);
//nsCRT::strtok is going destroy what we pass to it, so we need to make a copy of newsgroupsNames.
char *list = PL_strdup(newsgroupsNames);
char *token = nsnull;
char *rest = list;
nsString str("", eOneByte);
token = nsCRT::strtok(rest, ",", &rest);
while (token && *token) {
str = token;
@ -343,7 +349,8 @@ nsresult nsNntpService::DetermineHostForPosting(nsString &host, const char *news
printf("value = %s\n", str.GetBuffer());
#endif
nsString theRest("",eOneByte);
nsString currentHost("", eOneByte);
// does str start with "news:/"?
if (str.Find(kNewsRootURI) == 0) {
// we have news://group or news://host/group
@ -362,17 +369,34 @@ nsresult nsNntpService::DetermineHostForPosting(nsString &host, const char *news
PRInt32 slashpos = theRest.Find('/');
if (slashpos > 0 ) {
// theRest is "host/group"
theRest.Left(host, slashpos);
theRest.Left(currentHost, slashpos);
#ifdef DEBUG_NEWS
printf("host == %s\n", host.GetBuffer());
printf("currentHost == %s\n", currentHost.GetBuffer());
#endif
}
else {
// theRest is "group"
rv = FindHostFromGroup(host, str);
rv = FindHostFromGroup(currentHost, str);
PR_FREEIF(list);
if (NS_FAILED(rv)) return rv;
}
}
if (host == "") {
host = currentHost;
//we have our host, we're done.
//break;
}
else {
if (host != currentHost) {
printf("no cross posting to multiple hosts!\n");
PR_FREEIF(list);
return NS_ERROR_FAILURE;
}
}
str = "";
currentHost = "";
}
#ifdef DEBUG_NEWS
else {
@ -380,11 +404,8 @@ nsresult nsNntpService::DetermineHostForPosting(nsString &host, const char *news
}
#endif
token = nsCRT::strtok(rest, ",", &rest);
//we have our host, we're done.
//if (host != "") break;
}
PR_Free(list);
PR_FREEIF(list);
if (host != "")
return NS_OK;
@ -394,13 +415,149 @@ nsresult nsNntpService::DetermineHostForPosting(nsString &host, const char *news
////////////////////////////////////////////////////////////////////////////////////////
// nsINntpService support
////////////////////////////////////////////////////////////////////////////////////////
nsresult nsNntpService::PostMessage(nsFilePath &pathToFile, const char *newsgroupNames, nsIUrlListener * aUrlListener, nsIURI **_retval)
nsresult nsNntpService::ConvertNewsgroupsString(const char *newsgroupsNames, char **_retval)
{
nsresult rv = NS_OK;
if (!newsgroupsNames) return NS_ERROR_NULL_POINTER;
if (PL_strlen(newsgroupsNames) == 0) return NS_ERROR_FAILURE;
#ifdef DEBUG_seth
printf("newsgroupsNames == %s\n",newsgroupsNames);
#endif
// newsgroupsNames can be a comma seperated list of these:
// news://host/group
// news://group
// host/group
// group
//
// we are not going to allow the user to cross post to multiple hosts.
// if we detect that, we stop and return error.
// nsCRT::strtok is going destroy what we pass to it, so we need to make a copy of newsgroupsNames.
char *list = PL_strdup(newsgroupsNames);
char *token = nsnull;
char *rest = list;
nsString host("", eOneByte);
nsString str("", eOneByte);
nsString retvalStr("", eOneByte);
token = nsCRT::strtok(rest, ",", &rest);
while (token && *token) {
str = token;
str.StripWhitespace();
if (str != "") {
#ifdef DEBUG_seth
printf("value = %s\n", str.GetBuffer());
#endif
nsString currentHost("", eOneByte);
nsString theRest("",eOneByte);
// does str start with "news:/"?
if (str.Find(kNewsRootURI) == 0) {
// we have news://group or news://host/group
// set theRest to what's after news://
str.Right(theRest, str.Length() - kNewsRootURILen /* for news:/ */ - 1 /* for the slash */);
}
else {
theRest = str;
}
#ifdef DEBUG_seth
printf("theRest == %s\n",theRest.GetBuffer());
#endif
// theRest is "group" or "host/group"
PRInt32 slashpos = theRest.Find('/');
if (slashpos > 0 ) {
nsString currentGroup("",eOneByte);
// theRest is "host/group"
theRest.Left(currentHost, slashpos);
#ifdef DEBUG_seth
printf("currentHost == %s\n", currentHost.GetBuffer());
#endif
// from "host/group", put "group" into currentGroup;
theRest.Right(currentGroup, theRest.Length() - currentHost.Length() - 1);
NS_ASSERTION(currentGroup != "", "currentGroup is empty");
if (currentGroup == "") {
PR_FREEIF(list);
return NS_ERROR_FAILURE;
}
// build up the retvalStr;
if (retvalStr != "") {
retvalStr += ",";
}
retvalStr += currentGroup;
}
else {
// theRest is "group"
rv = FindHostFromGroup(currentHost, str);
if (NS_FAILED(rv)) {
PR_FREEIF(list);
return rv;
}
// build up the retvalStr;
if (retvalStr != "") {
retvalStr += ",";
}
retvalStr += str;
}
if (currentHost == "") {
printf("empty current host!\n");
PR_FREEIF(list);
return NS_ERROR_FAILURE;
}
if (host == "") {
printf("got a host, set it\n");
host = currentHost;
}
else {
if (host != currentHost) {
printf("no cross posting to multiple hosts!\n");
PR_FREEIF(list);
return NS_ERROR_FAILURE;
}
}
str = "";
currentHost = "";
}
#ifdef DEBUG_seth
else {
printf("nothing between two commas. ignore and keep going...\n");
}
#endif
token = nsCRT::strtok(rest, ",", &rest);
}
PR_FREEIF(list);
// caller will free with PR_FREEIF()
*_retval = PL_strdup(retvalStr.GetBuffer());
if (!*_retval) return NS_ERROR_OUT_OF_MEMORY;
#ifdef DEBUG_seth
printf("Newsgroups header = %s\n", *_retval);
#endif
return NS_OK;
}
nsresult nsNntpService::PostMessage(nsFilePath &pathToFile, const char *newsgroupsNames, nsIUrlListener * aUrlListener, nsIURI **_retval)
{
#ifdef DEBUG_NEWS
printf("nsNntpService::PostMessage(%s,%s,??,??)\n",(const char *)pathToFile,newsgroupNames);
printf("nsNntpService::PostMessage(%s,%s,??,??)\n",(const char *)pathToFile,newsgroupsNames);
#endif
if (!newsgroupNames) return NS_ERROR_NULL_POINTER;
if (PL_strlen(newsgroupNames) == 0) return NS_ERROR_FAILURE;
if (!newsgroupsNames) return NS_ERROR_NULL_POINTER;
if (PL_strlen(newsgroupsNames) == 0) return NS_ERROR_FAILURE;
NS_LOCK_INSTANCE();
@ -411,8 +568,8 @@ nsresult nsNntpService::PostMessage(nsFilePath &pathToFile, const char *newsgrou
if (NS_FAILED(rv) || !nntpUrl) return rv;
nsString host("",eOneByte);
rv = DetermineHostForPosting(host, newsgroupNames);
rv = DetermineHostForPosting(host, newsgroupsNames);
if (NS_FAILED(rv) || (host == "")) return rv;
#ifdef DEBUG_NEWS

View File

@ -34,6 +34,8 @@ public:
////////////////////////////////////////////////////////////////////////////////////////
// we suppport the nsINntpService Interface
////////////////////////////////////////////////////////////////////////////////////////
NS_IMETHOD ConvertNewsgroupsString(const char *newsgroupsStr, char **_retval);
NS_IMETHOD PostMessage(nsFilePath &pathToFile, const char *newsgroup, nsIUrlListener * aUrlListener, nsIURI **_retval);
NS_IMETHOD RunNewsUrl (nsString& urlString, nsString& newsgroupName, nsMsgKey aKey, nsISupports * aConsumer, nsIUrlListener * aUrlListener, nsIURI **_retval);