From 3e9a5b629dfb1eef50307a99d18e5907f81e0104 Mon Sep 17 00:00:00 2001 From: "sspitzer%netscape.com" Date: Sat, 10 Mar 2001 01:49:01 +0000 Subject: [PATCH] get copy of news message to work. take off my belt and give the news code the beating it deserves. remove some of the 4.x bloat. git-svn-id: svn://10.0.0.236/branches/MailNews_Performance_20010208_BRANCH@89189 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/mailnews/compose/src/makefile.win | 1 - .../compose/src/nsMsgComposeService.cpp | 12 +- mozilla/mailnews/news/build/nsMsgNewsCID.h | 27 +- .../mailnews/news/build/nsMsgNewsFactory.cpp | 18 +- mozilla/mailnews/news/public/Makefile.in | 4 - mozilla/mailnews/news/public/makefile.win | 4 - .../mailnews/news/public/nsIMsgNewsFolder.idl | 5 + .../news/public/nsIMsgOfflineNewsState.idl | 3 - .../news/public/nsINNTPArticleList.idl | 12 +- .../mailnews/news/public/nsINNTPCategory.idl | 41 - .../news/public/nsINNTPCategoryContainer.idl | 34 - mozilla/mailnews/news/public/nsINNTPHost.idl | 153 - .../mailnews/news/public/nsINNTPNewsgroup.idl | 65 - .../news/public/nsINNTPNewsgroupList.idl | 32 +- .../news/public/nsINntpIncomingServer.idl | 29 +- .../mailnews/news/public/nsINntpService.idl | 7 +- mozilla/mailnews/news/public/nsINntpUrl.idl | 14 - .../resources/locale/en-US/news.properties | 2 + mozilla/mailnews/news/src/MANIFEST | 3 - mozilla/mailnews/news/src/Makefile.in | 5 - mozilla/mailnews/news/src/makefile.win | 6 - .../mailnews/news/src/nsNNTPArticleList.cpp | 57 +- mozilla/mailnews/news/src/nsNNTPArticleList.h | 20 +- .../news/src/nsNNTPCategoryContainer.cpp | 76 - .../news/src/nsNNTPCategoryContainer.h | 48 - mozilla/mailnews/news/src/nsNNTPHost.cpp | 2643 ----------------- mozilla/mailnews/news/src/nsNNTPHost.h | 425 --- mozilla/mailnews/news/src/nsNNTPNewsgroup.cpp | 255 -- mozilla/mailnews/news/src/nsNNTPNewsgroup.h | 52 - .../mailnews/news/src/nsNNTPNewsgroupList.cpp | 328 +- .../mailnews/news/src/nsNNTPNewsgroupList.h | 21 +- mozilla/mailnews/news/src/nsNNTPProtocol.cpp | 456 ++- mozilla/mailnews/news/src/nsNNTPProtocol.h | 8 +- .../mailnews/news/src/nsNewsDownloader.cpp | 4 +- mozilla/mailnews/news/src/nsNewsFolder.cpp | 96 +- mozilla/mailnews/news/src/nsNewsFolder.h | 3 + .../news/src/nsNntpIncomingServer.cpp | 169 +- .../mailnews/news/src/nsNntpIncomingServer.h | 2 + mozilla/mailnews/news/src/nsNntpService.cpp | 421 +-- mozilla/mailnews/news/src/nsNntpService.h | 4 +- mozilla/mailnews/news/src/nsNntpUrl.cpp | 296 +- mozilla/mailnews/news/src/nsNntpUrl.h | 6 - 42 files changed, 812 insertions(+), 5055 deletions(-) delete mode 100644 mozilla/mailnews/news/public/nsINNTPCategory.idl delete mode 100644 mozilla/mailnews/news/public/nsINNTPCategoryContainer.idl delete mode 100644 mozilla/mailnews/news/public/nsINNTPHost.idl delete mode 100644 mozilla/mailnews/news/public/nsINNTPNewsgroup.idl delete mode 100644 mozilla/mailnews/news/src/nsNNTPCategoryContainer.cpp delete mode 100644 mozilla/mailnews/news/src/nsNNTPCategoryContainer.h delete mode 100644 mozilla/mailnews/news/src/nsNNTPHost.cpp delete mode 100644 mozilla/mailnews/news/src/nsNNTPHost.h delete mode 100644 mozilla/mailnews/news/src/nsNNTPNewsgroup.cpp delete mode 100644 mozilla/mailnews/news/src/nsNNTPNewsgroup.h diff --git a/mozilla/mailnews/compose/src/makefile.win b/mozilla/mailnews/compose/src/makefile.win index 0dacd2f8ff1..c57d4101ea8 100644 --- a/mozilla/mailnews/compose/src/makefile.win +++ b/mozilla/mailnews/compose/src/makefile.win @@ -63,7 +63,6 @@ CPP_OBJS= .\$(OBJDIR)\nsMsgCompFields.obj \ .\$(OBJDIR)\nsSmtpService.obj \ .\$(OBJDIR)\nsMsgComposeService.obj \ .\$(OBJDIR)\nsMsgComposeParams.obj \ - .\$(OBJDIR)\nsMsgComposeService.obj \ .\$(OBJDIR)\nsMsgComposeContentHandler.obj \ .\$(OBJDIR)\nsMsgCompose.obj \ .\$(OBJDIR)\nsMsgCreate.obj \ diff --git a/mozilla/mailnews/compose/src/nsMsgComposeService.cpp b/mozilla/mailnews/compose/src/nsMsgComposeService.cpp index 3fae2e2ec0f..4dbe2b0bae3 100644 --- a/mozilla/mailnews/compose/src/nsMsgComposeService.cpp +++ b/mozilla/mailnews/compose/src/nsMsgComposeService.cpp @@ -133,7 +133,8 @@ static nsresult openWindow( const char *chrome, nsIMsgComposeParams *params ) return rv; } -nsresult nsMsgComposeService::OpenComposeWindow(const char *msgComposeWindowURL, const char *originalMsgURI, +NS_IMETHODIMP +nsMsgComposeService::OpenComposeWindow(const char *msgComposeWindowURL, const char *originalMsgURI, MSG_ComposeType type, MSG_ComposeFormat format, nsIMsgIdentity * identity) { nsresult rv; @@ -201,9 +202,12 @@ nsresult nsMsgComposeService::OpenComposeWindow(const char *msgComposeWindowURL, pMsgComposeParams->SetComposeFields(pMsgCompFields); #ifdef MSGCOMP_TRACE_PERFORMANCE - char buff[256]; - sprintf(buff, "Start opening the window, message size = %d", GetMessageSizeFromURI(originalMsgURI)); - TimeStamp(buff, PR_TRUE); + // ducarroz, properly fix this in the case of new message (not a reply) + if (type != nsIMsgCompType::NewsPost) { + char buff[256]; + sprintf(buff, "Start opening the window, message size = %d", GetMessageSizeFromURI(originalMsgURI)); + TimeStamp(buff, PR_TRUE); + } #endif rv = openWindow(msgComposeWindowURL, pMsgComposeParams); } diff --git a/mozilla/mailnews/news/build/nsMsgNewsCID.h b/mozilla/mailnews/news/build/nsMsgNewsCID.h index 5a944c2ab6f..1f03f314fb3 100644 --- a/mozilla/mailnews/news/build/nsMsgNewsCID.h +++ b/mozilla/mailnews/news/build/nsMsgNewsCID.h @@ -53,12 +53,17 @@ // // nsNntpService // + +// not needed? who does nntp:/ ? #define NS_NNTPPROTOCOLINFO_CONTRACTID \ NS_MSGPROTOCOLINFO_CONTRACTID_PREFIX "nntp" + #define NS_NEWSPROTOCOLHANDLER_CONTRACTID \ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "news" #define NS_SNEWSPROTOCOLHANDLER_CONTRACTID \ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "snews" +#define NS_NEWSMESSAGEPROTOCOLHANDLER_CONTRACTID \ + NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "news_message" #define NS_NEWSMESSAGESERVICE_CONTRACTID \ "@mozilla.org/messenger/messageservice;1?type=news_message" #define NS_NNTPMESSAGESERVICE_CONTRACTID \ @@ -74,17 +79,6 @@ {0x80, 0x6e, 0x0, 0x60, 0x8, 0x12, 0x8c, 0x4e} \ } -// -// nsNNTPNewsgroup -// -#define NS_NNTPNEWSGROUP_CONTRACTID \ - "@mozilla.org/messenger/nntpnewsgroup;1" -#define NS_NNTPNEWSGROUP_CID \ -{ /* 2c070e8a-187e-11d3-8e02-004005263078 */ \ - 0x2c070e8a, 0x187e, 0x11d3, \ - {0x8e, 0x02, 0x00, 0x40, 0x05, 0x26, 0x30, 0x78} \ -} - // // nsNNTPNewsgroupPost // @@ -118,17 +112,6 @@ {0x97, 0x3e, 0x00, 0x80, 0x5f, 0x91, 0x6f, 0xd3} \ } -// -// nsNNTPHost -// -#define NS_NNTPHOST_CONTRACTID \ - "@mozilla.org/messenger/nntphost;1" -#define NS_NNTPHOST_CID \ -{ /* 339e5576-196a-11d3-929a-004005263078 */ \ - 0x339e5576, 0x196a, 0x11d3, \ - {0x92, 0x9a, 0x00, 0x40, 0x05, 0x26, 0x30, 0x78} \ -} - // // nsNntpUrl // diff --git a/mozilla/mailnews/news/build/nsMsgNewsFactory.cpp b/mozilla/mailnews/news/build/nsMsgNewsFactory.cpp index 1642b069cc2..2426799fc6a 100644 --- a/mozilla/mailnews/news/build/nsMsgNewsFactory.cpp +++ b/mozilla/mailnews/news/build/nsMsgNewsFactory.cpp @@ -39,11 +39,9 @@ #include "nsNntpUrl.h" #include "nsNntpService.h" #include "nsNntpIncomingServer.h" -#include "nsNNTPNewsgroup.h" #include "nsNNTPNewsgroupPost.h" #include "nsNNTPNewsgroupList.h" #include "nsNNTPArticleList.h" -#include "nsNNTPHost.h" #include "nsNewsDownloadDialogArgs.h" #include "nsIContentHandler.h" #include "nsCURILoader.h" @@ -52,8 +50,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsNntpUrl) NS_GENERIC_FACTORY_CONSTRUCTOR(nsNntpService) NS_GENERIC_FACTORY_CONSTRUCTOR(nsNntpIncomingServer) NS_GENERIC_FACTORY_CONSTRUCTOR(nsNNTPArticleList) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsNNTPHost) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsNNTPNewsgroup) NS_GENERIC_FACTORY_CONSTRUCTOR(nsNNTPNewsgroupPost) NS_GENERIC_FACTORY_CONSTRUCTOR(nsNNTPNewsgroupList) NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgNewsFolder) @@ -91,6 +87,10 @@ static nsModuleComponentInfo components[] = NS_NNTPSERVICE_CID, NS_NEWSPROTOCOLHANDLER_CONTRACTID, nsNntpServiceConstructor }, + { "News Message Protocol Handler", + NS_NNTPSERVICE_CID, + NS_NEWSMESSAGEPROTOCOLHANDLER_CONTRACTID, + nsNntpServiceConstructor }, { "Secure News Protocol Handler", NS_NNTPSERVICE_CID, NS_SNEWSPROTOCOLHANDLER_CONTRACTID, @@ -107,13 +107,9 @@ static nsModuleComponentInfo components[] = NS_NNTPINCOMINGSERVER_CID, NS_NNTPINCOMINGSERVER_CONTRACTID, nsNntpIncomingServerConstructor }, - { "NNTP Newsgroup", - NS_NNTPNEWSGROUP_CID, - NS_NNTPNEWSGROUP_CONTRACTID, - nsNNTPNewsgroupConstructor }, { "NNTP Newsgroup Post", NS_NNTPNEWSGROUPPOST_CID, - NS_NNTPNEWSGROUP_CONTRACTID, + NS_NNTPNEWSGROUPPOST_CONTRACTID, nsNNTPNewsgroupPostConstructor }, { "NNTP Newsgroup List", NS_NNTPNEWSGROUPLIST_CID, @@ -123,10 +119,6 @@ static nsModuleComponentInfo components[] = NS_NNTPARTICLELIST_CID, NS_NNTPARTICLELIST_CONTRACTID, nsNNTPArticleListConstructor }, - { "NNTP Host", - NS_NNTPHOST_CID, - NS_NNTPHOST_CONTRACTID, - nsNNTPHostConstructor }, { "News download dialog args", NS_NEWSDOWNLOADDIALOGARGS_CID, NS_NEWSDOWNLOADDIALOGARGS_CONTRACTID, diff --git a/mozilla/mailnews/news/public/Makefile.in b/mozilla/mailnews/news/public/Makefile.in index 80fc7d95c15..3d02fff83bb 100644 --- a/mozilla/mailnews/news/public/Makefile.in +++ b/mozilla/mailnews/news/public/Makefile.in @@ -31,10 +31,6 @@ MODULE = msgnews XPIDLSRCS = \ nsIMsgOfflineNewsState.idl \ nsINNTPArticleList.idl \ - nsINNTPCategory.idl \ - nsINNTPCategoryContainer.idl \ - nsINNTPHost.idl \ - nsINNTPNewsgroup.idl \ nsINNTPNewsgroupList.idl \ nsINNTPProtocol.idl \ nsINntpIncomingServer.idl \ diff --git a/mozilla/mailnews/news/public/makefile.win b/mozilla/mailnews/news/public/makefile.win index a5a5bb72ee6..696a070690c 100644 --- a/mozilla/mailnews/news/public/makefile.win +++ b/mozilla/mailnews/news/public/makefile.win @@ -25,10 +25,6 @@ MODULE=msgnews XPIDLSRCS= \ .\nsIMsgOfflineNewsState.idl \ .\nsINNTPArticleList.idl \ - .\nsINNTPCategory.idl \ - .\nsINNTPCategoryContainer.idl \ - .\nsINNTPHost.idl \ - .\nsINNTPNewsgroup.idl \ .\nsINNTPNewsgroupList.idl \ .\nsINNTPNewsgroupPost.idl \ .\nsINNTPProtocol.idl \ diff --git a/mozilla/mailnews/news/public/nsIMsgNewsFolder.idl b/mozilla/mailnews/news/public/nsIMsgNewsFolder.idl index 2182820cbf5..dc32a45163f 100644 --- a/mozilla/mailnews/news/public/nsIMsgNewsFolder.idl +++ b/mozilla/mailnews/news/public/nsIMsgNewsFolder.idl @@ -31,6 +31,11 @@ interface nsIMsgNewsFolder : nsISupports { attribute string groupUsername; attribute string groupPassword; + /** the ascii name for the newsgroup. + * newsgroup names are always ascii, and this can help simply + * the code, to prevent use from having to get the name (as a wstring) + * and then converting it back to ascii. + */ readonly attribute string asciiName; readonly attribute nsINntpIncomingServer nntpServer; attribute boolean saveArticleOffline; diff --git a/mozilla/mailnews/news/public/nsIMsgOfflineNewsState.idl b/mozilla/mailnews/news/public/nsIMsgOfflineNewsState.idl index bd15db6f251..938631766e3 100644 --- a/mozilla/mailnews/news/public/nsIMsgOfflineNewsState.idl +++ b/mozilla/mailnews/news/public/nsIMsgOfflineNewsState.idl @@ -25,18 +25,15 @@ */ #include "nsISupports.idl" -#include "nsINNTPNewsgroup.idl" [scriptable, uuid(921AC210-96B5-11d2-B7EB-00805F05FFA5)] interface nsIMsgOfflineNewsState : nsISupports { - attribute nsINNTPNewsgroup newsgroup; /* outputBuffer is actually * a buffer to dump data into, but we normally pass it NET_Socket_Buffer, * which is constant. The implementation should only allocate a new * buffer if *outputBuffer is NULL. */ - long Process(out string outputBuffer, in long bufferSize); long Interrupt(); }; diff --git a/mozilla/mailnews/news/public/nsINNTPArticleList.idl b/mozilla/mailnews/news/public/nsINNTPArticleList.idl index caefdc5744e..6c5aeae06a8 100644 --- a/mozilla/mailnews/news/public/nsINNTPArticleList.idl +++ b/mozilla/mailnews/news/public/nsINNTPArticleList.idl @@ -21,15 +21,13 @@ */ #include "nsISupports.idl" -#include "nsINNTPNewsgroup.idl" -#include "nsINNTPHost.idl" + +interface nsIMsgNewsFolder; [scriptable, uuid(921AC214-96B5-11d2-B7EB-00805F05FFA5)] interface nsINNTPArticleList : nsISupports { - - void Initialize(in nsINNTPHost newsHost, in nsINNTPNewsgroup newsgroup); - void AddArticleKey(in long key); - void FinishAddingArticleKeys(); - + void initialize(in nsIMsgNewsFolder newsFolder); + void addArticleKey(in long key); + void finishAddingArticleKeys(); }; diff --git a/mozilla/mailnews/news/public/nsINNTPCategory.idl b/mozilla/mailnews/news/public/nsINNTPCategory.idl deleted file mode 100644 index f26aba52e27..00000000000 --- a/mozilla/mailnews/news/public/nsINNTPCategory.idl +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#include "nsISupports.idl" -#include "nsIMsgGroupRecord.idl" -#include "nsINNTPNewsgroup.idl" - -[scriptable, uuid(203b2120-b256-11d2-b7f0-00805f05ffa5)] -interface nsINNTPCategory : nsISupports { - nsINNTPNewsgroup BuildCategoryTree(in nsINNTPNewsgroup parent, - in string catName, - in nsIMsgGroupRecord group, - in short depth); - - nsINNTPNewsgroup AddToCategoryTree(in nsINNTPNewsgroup parent, - in string groupName, - in nsIMsgGroupRecord group); - - nsINNTPNewsgroup CloneIntoNewsFolder(); - nsINNTPNewsgroup GetRootCategory(); -}; - diff --git a/mozilla/mailnews/news/public/nsINNTPCategoryContainer.idl b/mozilla/mailnews/news/public/nsINNTPCategoryContainer.idl deleted file mode 100644 index 752bf7d0c9e..00000000000 --- a/mozilla/mailnews/news/public/nsINNTPCategoryContainer.idl +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#include "nsISupports.idl" -#include "nsINNTPNewsgroup.idl" - -interface nsINNTPNewsgroup; - -[scriptable, uuid(cb36d510-b249-11d2-b7ef-00805f05ffa5)] -interface nsINNTPCategoryContainer : nsISupports { - - attribute nsINNTPNewsgroup rootCategory; - - void Initialize(in nsINNTPNewsgroup rootCategory); -}; diff --git a/mozilla/mailnews/news/public/nsINNTPHost.idl b/mozilla/mailnews/news/public/nsINNTPHost.idl deleted file mode 100644 index 4792c92112e..00000000000 --- a/mozilla/mailnews/news/public/nsINNTPHost.idl +++ /dev/null @@ -1,153 +0,0 @@ -/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#include "nsISupports.idl" - -interface nsINNTPNewsgroup; -interface nsINNTPNewsgroupList; -interface nsINntpUrl; - -[scriptable, uuid(6b128da0-d74f-11d2-b7f9-00805f05ffa5)] -interface nsINNTPHost : nsISupports { - - void Initialize(in nsINntpUrl runningURL, in string username, in string hostname); - - attribute boolean supportsExtensions; - void AddExtension(in string extension); - boolean QueryExtension(in string extension); - - attribute boolean postingAllowed; - attribute boolean pushAuth; - attribute unsigned long lastUpdatedTime; - - /* look up the newsgroup list for the given name */ - nsINNTPNewsgroupList GetNewsgroupList(in string name); - - /* given a newsgroup name, find or create the given name */ - nsINNTPNewsgroup FindNewsgroup(in string name, in boolean create); - - /* libnet callbacks for Dredd NNTP extensions - * please document if you know how these work - */ - void AddPropertyForGet(in string name, in string value); - string QueryPropertyForGet(in string name); - - void AddSearchableGroup(in string name); - boolean QuerySearchableGroup(in string name); - - void AddVirtualGroup(in string responseText); - void SetIsVirtualGroup(in string name, in boolean isVirtual); - boolean GetIsVirtualGroup(in string name - /*, nsIMsgGroupRecord inGroupRecord */); - - - void AddSearchableHeader(in string headerName); - boolean QuerySearchableHeader(in string headerName); - - /* this used to just call pane->GetMaster()->AddNewsGroup(url) */ - /* void AddSubscribedNewsgroup(in string url); */ - - /* In response to an NNTP GROUP command, the server said - * the group doesn't exist - */ - void GroupNotFound(in string group, in boolean opening); - - /* Tell the subscribe pane about a new newsgroup we noticed. */ - /* XXX should xactive flags be a long? */ - void AddNewNewsgroup(in string name, - in long first, in long last, - in string flags, in boolean xactiveFlags); - - /* formerly GetNewsRCCount() */ - /* After displaying a list of newsgroups, we need the NNTP module to go and - run "GROUP" commands for the ones for which we don't know the unread - article count. This function returns a count of how many groups we think - we're going to need this for (so we can display progress in a reasonable - way). - */ - long GetNumGroupsNeedingCounts(); - - /* formerly GetNewsRCGroup() */ - /* Gets the name of the next group that we want to get article counts for. - MSG_DisplaySubscribedGroup() should get called with this group before - this call happens again. */ - string GetFirstGroupNeedingCounts(); - - /* In response to a "news://host/" URL; this is called once for each group - that was returned by MSG_GetNewsRCGroup(), after the NNTP GROUP - command has been run. It's also called whenever we actually visit the - group (the user clicks on the newsgroup line), in case the data has - changed since the initial passthrough. The "nowvisiting" parameter - is TRUE in the latter case, FALSE otherwise. */ - void DisplaySubscribedGroup(in nsINNTPNewsgroup newsgroup, - in long first_message, in long last_message, - in long total_messages, - in boolean visit_now); - - string GetFirstGroupNeedingExtraInfo(); - void SetGroupNeedsExtraInfo(in string name, in boolean needsExtraInfo); - - - /* News servers work better if you ask for message numbers instead of IDs. - So, the NNTP module asks us what the group and number of an ID is with - this. If we don't know, we return 0 for both. If the pane is not a - thead or message pane, this routine will fail. - */ - void GetNewsgroupAndNumberOfID(in string message_id, - out nsINNTPNewsgroup group, - out unsigned long message_number); - - - void SetPrettyName(in string name, in string prettyName); - - /* Write out the newsrc for this host right now. In general, either - MarkDirty() or WriteIfDirty() should be called instead. */ - void WriteNewsrc(); - - /* Write out the newsrc for this host right now, if anything has changed - in it. */ - void WriteIfDirty(); - - /* Note that something has changed, and we need to rewrite the newsrc file - for this host at some point. */ - void MarkDirty(); - - attribute string newsRCFilename; - - nsINNTPNewsgroup FindGroup(in string name); - nsINNTPNewsgroup AddGroup(in string name - /* , msg_GroupRecord *inGroupRecord */ ); - void RemoveGroupByName(in string name); - void RemoveGroup(in nsINNTPNewsgroup group); - - /* Name of directory to store newsgroup - databases in. This needs to have - "/name" appended to it, and the - whole thing can be passed to the XP_File - stuff with a type of xpXoverCache. - */ - readonly attribute string dbDirName; - - /* this should actually return a list of strings..how to do in XPIDL? */ - string GetGroupList(); - -}; diff --git a/mozilla/mailnews/news/public/nsINNTPNewsgroup.idl b/mozilla/mailnews/news/public/nsINNTPNewsgroup.idl deleted file mode 100644 index ee4494f4c95..00000000000 --- a/mozilla/mailnews/news/public/nsINNTPNewsgroup.idl +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -/* - * network-oriented interface to newsgroups. - * This is similar to the old MSG_NewsFolderInfo but is an interface - * only NNTP uses for talking to the news server and maintaining state. - * - */ - - -#include "nsISupports.idl" - -%{ C++ -#include "nsMsgKeySet.h" -%} - -interface nsMsgKeySet; -interface nsINNTPNewsgroupList; - -[scriptable, uuid(1A39CD90-ACAF-11d2-B7EE-00805F05FFA5)] -interface nsINNTPNewsgroup : nsISupports { - - attribute string name; - attribute string prettyName; - - attribute boolean needsExtraInfo; - - boolean IsOfflineArticle(in long num); - - attribute boolean category; - - attribute boolean subscribed; - attribute boolean wantNewTotals; - attribute nsINNTPNewsgroupList newsgroupList; - - void UpdateSummaryFromNNTPInfo(in long oldest, - in long youngest, - in long total_messages); - - void Initialize(in string name, - in nsMsgKeySet set, - in boolean subscribed); -}; - - diff --git a/mozilla/mailnews/news/public/nsINNTPNewsgroupList.idl b/mozilla/mailnews/news/public/nsINNTPNewsgroupList.idl index bf9d454ae27..d877ba101a8 100644 --- a/mozilla/mailnews/news/public/nsINNTPNewsgroupList.idl +++ b/mozilla/mailnews/news/public/nsINNTPNewsgroupList.idl @@ -26,28 +26,23 @@ * to destroy the DBView) */ #include "nsISupports.idl" -#include "nsINNTPHost.idl" -#include "nsINNTPNewsgroup.idl" -interface nsINNTPHost; -interface nsINNTPNewsgroup; +interface nsIMsgNewsFolder; interface nsINntpUrl; interface nsIMsgWindow; [scriptable, uuid(E628ED19-9452-11d2-B7EA-00805F05FFA5)] interface nsINNTPNewsgroupList : nsISupports { - - /* These calls are used by libnet to determine which articles it ought to - get in a big newsgroup. */ - - - long GetRangeOfArtsToDownload(in nsIMsgWindow aMsgWindow, in long first_message, + + void initialize(in nsINntpUrl runningURL, in nsIMsgNewsFolder newsFolder); + + long getRangeOfArtsToDownload(in nsIMsgWindow aMsgWindow, in long first_message, in long last_message, in long maxextra, out long real_first_message, out long real_last_message); - void AddToKnownArticles(in long first_message, in long last_message); + void addToKnownArticles(in long first_message, in long last_message); /* The NNTP module of netlib calls these to feed XOVER data to the message @@ -61,15 +56,12 @@ interface nsINNTPNewsgroupList : nsISupports { line to, followed by a "\n". This is used by the XOVER-caching code. */ /* the XOVER Sink should maintain the ListNewsGroupState */ - void InitXOVER(in long first_message, in long last_message); - void ProcessXOVERLINE(in string line, out unsigned long status); - void ProcessNonXOVER(in string line); - void ResetXOVER(); - void FinishXOVERLINE(in long status, out long newstatus); - void ClearXOVERState(); - string GetGroupName(); - - void Initialize(in nsINNTPHost host, in nsINntpUrl runningURL, in nsINNTPNewsgroup newsgroup, in string username, in string hostname, in string groupname); + void initXOVER(in long first_message, in long last_message); + void processXOVERLINE(in string line, out unsigned long status); + void processNonXOVER(in string line); + void resetXOVER(); + void finishXOVERLINE(in long status, out long newstatus); + void clearXOVERState(); attribute boolean getOldMessages; }; diff --git a/mozilla/mailnews/news/public/nsINntpIncomingServer.idl b/mozilla/mailnews/news/public/nsINntpIncomingServer.idl index c5a68380229..31824bca423 100644 --- a/mozilla/mailnews/news/public/nsINntpIncomingServer.idl +++ b/mozilla/mailnews/news/public/nsINntpIncomingServer.idl @@ -64,9 +64,9 @@ interface nsINntpIncomingServer : nsISupports { void displaySubscribedGroup(in nsIMsgNewsFolder msgFolder, in long firstMessage, in long lastMessage, in long totalMessages); - void GetNntpConnection(in nsIURI url, in nsIMsgWindow window, + void getNntpConnection(in nsIURI url, in nsIMsgWindow window, out nsINNTPProtocol aNntpConnection); - void RemoveConnection(in nsINNTPProtocol aNntpConnection); + void removeConnection(in nsINNTPProtocol aNntpConnection); /* used for auto subscribing */ boolean containsNewsgroup(in string name); @@ -75,4 +75,29 @@ interface nsINntpIncomingServer : nsISupports { /* used for the subscribe dialog */ void addNewsgroupToList(in string name); + attribute boolean supportsExtensions; + void addExtension(in string extension); + boolean queryExtension(in string extension); + + attribute boolean postingAllowed; + attribute boolean pushAuth; + attribute unsigned long lastUpdatedTime; + + void addPropertyForGet(in string name, in string value); + string queryPropertyForGet(in string name); + + void addSearchableGroup(in string name); + boolean querySearchableGroup(in string name); + + void addSearchableHeader(in string headerName); + boolean querySearchableHeader(in string headerName); + + nsIMsgNewsFolder findGroup(in string name); + + readonly attribute string firstGroupNeedingExtraInfo; + void setGroupNeedsExtraInfo(in string name, in boolean needsExtraInfo); + + void groupNotFound(in string group, in boolean opening); + + void setPrettyName(in string name, in string prettyName); }; diff --git a/mozilla/mailnews/news/public/nsINntpService.idl b/mozilla/mailnews/news/public/nsINntpService.idl index 915a76079b8..e1056296fc2 100644 --- a/mozilla/mailnews/news/public/nsINntpService.idl +++ b/mozilla/mailnews/news/public/nsINntpService.idl @@ -42,7 +42,7 @@ interface nsINntpService : nsISupports { nsIURI getNewNews (in nsINntpIncomingServer nntpServer, in string uri, in boolean getOld, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow); - nsIURI cancelMessages (in string hostname, in string newsgroupname, in nsISupportsArray messages, in nsISupports aConsumer, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow); + nsIURI cancelMessage(in string uri, in nsISupports aConsumer, in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow); void getListOfGroupsOnServer(in nsINntpIncomingServer nntpServer, in nsIMsgWindow aMsgWindow); @@ -50,5 +50,10 @@ interface nsINntpService : nsISupports { nsIURI fetchMessage(in nsIMsgFolder newsFolder, in nsMsgKey key, in nsIMsgWindow aMsgWindow, in nsISupports aConsumer, in nsIUrlListener aUrlListener); + /** + * can handle news_message:// and news:// + */ + void decomposeNewsURI(in string uri, out nsIMsgFolder folder, out nsMsgKey key); + }; diff --git a/mozilla/mailnews/news/public/nsINntpUrl.idl b/mozilla/mailnews/news/public/nsINntpUrl.idl index dd2c5cc9369..d76a0dd8175 100644 --- a/mozilla/mailnews/news/public/nsINntpUrl.idl +++ b/mozilla/mailnews/news/public/nsINntpUrl.idl @@ -24,11 +24,7 @@ #include "MailNewsTypes2.idl" %{ C++ -#include "nsINNTPHost.h" -#include "nsINNTPArticleList.h" -#include "nsINNTPNewsgroup.h" #include "nsIMsgOfflineNewsState.h" -#include "nsINNTPNewsgroupList.h" #include "nsINNTPNewsgroupPost.h" #include "nsIMsgMailNewsUrl.h" @@ -37,26 +33,16 @@ %} interface nsIMsgDBHdr; -interface nsINNTPHost; -interface nsINNTPArticleList; -interface nsINNTPNewsgroup; interface nsIMsgOfflineNewsState; -interface nsINNTPNewsgroupList; interface nsINNTPNewsgroupPost; typedef long nsNewsAction; [scriptable, uuid(BDD12930-A682-11d2-804C-006008128C4E)] interface nsINntpUrl : nsISupports { - attribute nsINNTPHost nntpHost; - attribute nsINNTPArticleList nntpArticleList; - attribute nsINNTPNewsgroup newsgroup; attribute nsIMsgOfflineNewsState offlineNewsState; - attribute nsINNTPNewsgroupList newsgroupList; attribute nsINNTPNewsgroupPost messageToPost; readonly attribute nsIMsgDBHdr messageHeader; - attribute nsMsgKey messageKey; - attribute string newsgroupName; attribute nsNewsAction newsAction; attribute boolean getOldMessages; diff --git a/mozilla/mailnews/news/resources/locale/en-US/news.properties b/mozilla/mailnews/news/resources/locale/en-US/news.properties index 7bba6afbb95..4c88078e180 100644 --- a/mozilla/mailnews/news/resources/locale/en-US/news.properties +++ b/mozilla/mailnews/news/resources/locale/en-US/news.properties @@ -46,6 +46,8 @@ bytesReceived=Downloading newsgroups: %S received (%SK read at %SK/sec) checkingForNewNews=Checking newsgroup %S of %S for new messages downloadingArticlesForOffline=%Downloading articles %S-%S in %S +onlyCancelOneMessage=You can only cancel one article at a time. + # LOCALIZATION NOTE (Error -304): In the following item, don't translate "NNTP" # Error - server error ## @name NNTP_ERROR_MESSAGE diff --git a/mozilla/mailnews/news/src/MANIFEST b/mozilla/mailnews/news/src/MANIFEST index edadfdf9531..e6a2d948738 100644 --- a/mozilla/mailnews/news/src/MANIFEST +++ b/mozilla/mailnews/news/src/MANIFEST @@ -23,12 +23,9 @@ nsNNTPProtocol.h nsNntpUrl.h nsNNTPNewsgroupList.h -nsNNTPNewsgroup.h nntpCore.h nsNNTPNewsgroupPost.h nsNewsFolder.h nsNntpIncomingServer.h nsNewsUtils.h nsNNTPArticleList.h -nsNNTPHost.h -nsNNTPCategoryContainer.h diff --git a/mozilla/mailnews/news/src/Makefile.in b/mozilla/mailnews/news/src/Makefile.in index 33fa1b469e1..b86e584546a 100644 --- a/mozilla/mailnews/news/src/Makefile.in +++ b/mozilla/mailnews/news/src/Makefile.in @@ -32,12 +32,10 @@ REQUIRES = xpcom mailnews msgbase msgbaseutil necko msgdb locale mork dom js rdf CPPSRCS = \ nsNNTPArticleList.cpp \ - nsNNTPNewsgroup.cpp \ nsNNTPNewsgroupList.cpp \ nsNNTPNewsgroupPost.cpp \ nsNNTPProtocol.cpp \ nsNntpUrl.cpp \ - nsNNTPHost.cpp \ nsNntpService.cpp \ nsNewsFolder.cpp \ nsNntpIncomingServer.cpp \ @@ -51,15 +49,12 @@ EXPORTS = \ nsNntpUrl.h \ nsNNTPArticleList.h \ nsNNTPNewsgroupList.h \ - nsNNTPNewsgroup.h \ nsNNTPNewsgroupPost.h \ nntpCore.h \ nsNntpService.h \ nsNewsFolder.h \ nsNntpIncomingServer.h \ nsNewsUtils.h \ - nsNNTPHost.h \ - nsNNTPCategoryContainer.h \ nsNewsDownloadDialogArgs.h \ $(NULL) diff --git a/mozilla/mailnews/news/src/makefile.win b/mozilla/mailnews/news/src/makefile.win index 86317dbb3d2..5f2e581fa4e 100644 --- a/mozilla/mailnews/news/src/makefile.win +++ b/mozilla/mailnews/news/src/makefile.win @@ -31,15 +31,12 @@ EXPORTS= nsNNTPProtocol.h \ nsNntpUrl.h \ nsNNTPNewsgroupList.h \ nsNNTPArticleList.h \ - nsNNTPNewsgroup.h \ nntpCore.h \ nsNNTPNewsgroupPost.h \ nsNntpService.h \ nsNewsFolder.h \ nsNntpIncomingServer.h \ nsNewsUtils.h \ - nsNNTPHost.h \ - nsNNTPCategoryContainer.h \ nsNewsDownloadDialogArgs.h \ $(NULL) @@ -53,9 +50,6 @@ CPP_OBJS= .\$(OBJDIR)\nsNNTPProtocol.obj \ .\$(OBJDIR)\nsNNTPArticleList.obj \ .\$(OBJDIR)\nsNNTPNewsgroupList.obj \ .\$(OBJDIR)\nsNNTPNewsgroupPost.obj \ - .\$(OBJDIR)\nsNNTPHost.obj \ - .\$(OBJDIR)\nsNNTPNewsgroup.obj \ - .\$(OBJDIR)\nsNNTPCategoryContainer.obj \ .\$(OBJDIR)\nsNntpService.obj \ .\$(OBJDIR)\nsNewsFolder.obj \ .\$(OBJDIR)\nsNntpIncomingServer.obj \ diff --git a/mozilla/mailnews/news/src/nsNNTPArticleList.cpp b/mozilla/mailnews/news/src/nsNNTPArticleList.cpp index 53bf055448b..949c22fda16 100644 --- a/mozilla/mailnews/news/src/nsNNTPArticleList.cpp +++ b/mozilla/mailnews/news/src/nsNNTPArticleList.cpp @@ -22,11 +22,12 @@ #include "msgCore.h" // precompiled header... +#include "nsCOMPtr.h" #include "nsNNTPNewsgroupList.h" -#include "nsINNTPHost.h" #include "nsINNTPArticleList.h" #include "nsMsgKeySet.h" #include "nsNNTPArticleList.h" +#include "nsIMsgFolder.h" NS_IMPL_ISUPPORTS1(nsNNTPArticleList, nsINNTPArticleList) @@ -36,53 +37,37 @@ nsNNTPArticleList::nsNNTPArticleList() } nsresult -nsNNTPArticleList::Initialize(nsINNTPHost * newsHost, - nsINNTPNewsgroup* newsgroup) +nsNNTPArticleList::Initialize(nsIMsgNewsFolder *newsFolder) { - m_host = newsHost; - m_newsgroup = newsgroup; -#ifdef HAVE_PANES - m_pane = pane; -#endif -#ifdef HAVE_NEWSDB - m_newsDB = NULL; -#endif - m_idsOnServer.set = nsMsgKeySet::Create(); -#ifdef HAVE_PANES - nsINNTPNewsgroup *newsFolder = m_pane->GetMaster()->FindNewsFolder(host, groupName, PR_FALSE); - if (newsFolder) - { - char *url = newsFolder->BuildUrl(NULL, nsMsgKey_None); -#ifdef HAVE_NEWSDB - if (url) - NewsGroupDB::Open(url, m_pane->GetMaster(), &m_newsDB); - if (m_newsDB) - m_newsDB->ListAllIds(m_idsInDB); -#endif - m_dbIndex = 0; + nsresult rv; + + m_newsFolder = newsFolder; - PR_FREEIF(url); - } -#endif - return NS_MSG_SUCCESS; + nsCOMPtr folder = do_QueryInterface(m_newsFolder, &rv); + NS_ENSURE_SUCCESS(rv,rv); + + rv = folder->GetMsgDatabase(nsnull /* msgWindow */, getter_AddRefs(m_newsDB)); + NS_ENSURE_SUCCESS(rv,rv); + return NS_OK; } nsNNTPArticleList::~nsNNTPArticleList() { -#ifdef HAVE_NEWSDB - if (m_newsDB) - m_newsDB->Close(); -#endif + if (m_newsDB) { + m_newsDB->Commit(nsMsgDBCommitType::kSessionCommit); + m_newsDB->Close(PR_TRUE); + m_newsDB = nsnull; + } } nsresult nsNNTPArticleList::AddArticleKey(PRInt32 key) { #ifdef DEBUG_NEWS - char * groupname = nsnull; - if (m_newsgroup) - m_newsgroup->GetName(&groupname); - printf("Adding article key %d for group %s.\n", key, groupname ? groupname : "unspecified"); + nsXPIDLCString groupname + if (m_newsFolder) + m_newsFolder->GetAsciiName(getter_Copies(groupname)); + printf("Adding article key %d for group %s.\n", key, (const char *)groupname); PR_FREEIF(groupname); #endif m_idsOnServer.set->Add(key); diff --git a/mozilla/mailnews/news/src/nsNNTPArticleList.h b/mozilla/mailnews/news/src/nsNNTPArticleList.h index 50441bf6568..660355a8e17 100644 --- a/mozilla/mailnews/news/src/nsNNTPArticleList.h +++ b/mozilla/mailnews/news/src/nsNNTPArticleList.h @@ -23,10 +23,10 @@ #ifndef nsNNTPArticleList_h___ #define nsNNTPArticleList_h___ +#include "nsCOMPtr.h" #include "nsINNTPArticleList.h" - -/* XXX - temporary hack so this will compile */ -typedef PRUint32 nsMsgKey; +#include "nsIMsgNewsFolder.h" +#include "nsIMsgDatabase.h" class nsNNTPArticleList : public nsINNTPArticleList #ifdef HAVE_CHANGELISTENER @@ -43,15 +43,11 @@ public: // other stuff protected: struct MSG_NewsKnown m_idsOnServer; -#ifdef HAVE_PANES - MSG_Pane *m_pane; -#endif - /* formerly m_groupName */ - nsINNTPNewsgroup *m_newsgroup; - const nsINNTPHost *m_host; -#ifdef HAVE_NEWSDB - NewsGroupDB *m_newsDB; -#endif + + /* formerly m_groupName */ + nsCOMPtr m_newsFolder; + nsCOMPtr m_newsDB; + #ifdef HAVE_IDARRAY IDArray m_idsInDB; #ifdef DEBUG_bienvenu diff --git a/mozilla/mailnews/news/src/nsNNTPCategoryContainer.cpp b/mozilla/mailnews/news/src/nsNNTPCategoryContainer.cpp deleted file mode 100644 index 445ccec4298..00000000000 --- a/mozilla/mailnews/news/src/nsNNTPCategoryContainer.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Pierre Phaneuf - */ - - /* This is a stub event sink for a NNTP Newsgroup introduced by mscott to test - the NNTP protocol */ - -#include "nsNNTPCategoryContainer.h" - -NS_IMPL_ISUPPORTS1(nsNNTPCategoryContainer, nsINNTPCategoryContainer) - -nsNNTPCategoryContainer::nsNNTPCategoryContainer() -{ - NS_INIT_REFCNT(); - m_newsgroup = nsnull; -} - -nsNNTPCategoryContainer::~nsNNTPCategoryContainer() -{ - printf("Destroying category container. \n"); - NS_IF_RELEASE(m_newsgroup); -} - -nsresult nsNNTPCategoryContainer::GetRootCategory(nsINNTPNewsgroup * *aRootCategory) -{ - if (aRootCategory) - { - *aRootCategory = m_newsgroup; - NS_IF_ADDREF(m_newsgroup); - } - - return NS_OK; -} - - -nsresult nsNNTPCategoryContainer::Initialize(nsINNTPNewsgroup * aRootCategory) -{ - // for now, just set the root category. - return SetRootCategory(aRootCategory); -} - -nsresult nsNNTPCategoryContainer::SetRootCategory(nsINNTPNewsgroup * aRootCategory) -{ - if (aRootCategory) - { - char * name = nsnull; - aRootCategory->GetName(&name); -#ifdef DEBUG_NEWS - printf("Setting root category for container to %s", name ? name : "unspecified"); -#endif - m_newsgroup = aRootCategory; - NS_IF_ADDREF(m_newsgroup); - } - return NS_OK; - -} - diff --git a/mozilla/mailnews/news/src/nsNNTPCategoryContainer.h b/mozilla/mailnews/news/src/nsNNTPCategoryContainer.h deleted file mode 100644 index 9cf8bf53014..00000000000 --- a/mozilla/mailnews/news/src/nsNNTPCategoryContainer.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#ifndef __nsNNTPCategoryContainer_h -#define __nsNNTPCategoryContainer_h - -#include "nsINNTPCategoryContainer.h" -#include "nsINNTPNewsgroup.h" - -#include "nsISupports.h" /* interface nsISupports */ - -#include "nscore.h" -#include "plstr.h" -#include "prmem.h" -//#include - -class nsNNTPCategoryContainer : public nsINNTPCategoryContainer { - public: - nsNNTPCategoryContainer(); - virtual ~nsNNTPCategoryContainer(); - - NS_DECL_ISUPPORTS - NS_DECL_NSINNTPCATEGORYCONTAINER - -protected: - nsINNTPNewsgroup * m_newsgroup; -}; - -#endif diff --git a/mozilla/mailnews/news/src/nsNNTPHost.cpp b/mozilla/mailnews/news/src/nsNNTPHost.cpp deleted file mode 100644 index 6d38298a122..00000000000 --- a/mozilla/mailnews/news/src/nsNNTPHost.cpp +++ /dev/null @@ -1,2643 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Pierre Phaneuf - * Henrik Gemal - */ - -#include "nsNNTPHost.h" -#include "prlog.h" - -#include "nsMsgNewsCID.h" - -static NS_DEFINE_CID(kNNTPNewsgroupCID, NS_NNTPNEWSGROUP_CID); -static NS_DEFINE_CID(kNNTPNewsgroupListCID, NS_NNTPNEWSGROUPLIST_CID); - -#if defined(XP_UNIX) || defined(XP_BEOS) -static const char LINEBREAK_START = '\012'; -#else -static const char LINEBREAK_START = '\015'; -#endif - -#define PROTOCOL_DEBUG - -nsNNTPHost * nsNNTPHost::M_FileOwner = nsnull; - -NS_IMPL_ISUPPORTS1(nsNNTPHost, nsINNTPHost) - - -nsNNTPHost::nsNNTPHost() -{ - NS_INIT_REFCNT(); - - m_hostname = nsnull; - m_username = nsnull; - m_groups = nsnull; - m_newsgrouplists = nsnull; - m_hostinfo = nsnull; - m_optionLines = nsnull; - m_filename = nsnull; - m_dbfilename = nsnull; - m_writetimer = nsnull; - m_urlbase = nsnull; - m_searchableGroupCharsets = nsnull; - m_groupTree = nsnull; - m_hostinfofilename = nsnull; - M_FileOwner = nsnull; - m_groupFile = nsnull; - m_groupFilePermissions = nsnull; - m_block = nsnull; - m_runningURL = nsnull; -} - -/* we're not supposed to implement this */ - -nsNNTPHost::~nsNNTPHost() -{ - CleanUp(); -} - -nsresult nsNNTPHost::Initialize(nsINntpUrl *runningURL, const char *username, const char *hostname) -{ - m_hostname = new char [PL_strlen(hostname) + 1]; - PL_strcpy(m_hostname, hostname); - - if (username) { - m_username = new char [PL_strlen(username) + 1]; - PL_strcpy(m_username, username); - } - else { - m_username = nsnull; - } - - m_searchableGroupCharsets = PL_NewHashTable(20, PL_HashString, PL_CompareStrings, PL_CompareValues, nsnull, nsnull); - - m_optionLines = nsnull; - m_filename = nsnull; - m_groups = nsnull; - m_newsgrouplists = nsnull; - m_dbfilename = nsnull; - m_dirty = 0; - m_writetimer = nsnull; - m_postingAllowed = PR_TRUE; - m_supportsExtensions = PR_FALSE; - m_pushAuth = PR_FALSE; - m_groupSucceeded = PR_FALSE; - m_lastGroupUpdate = 0; - m_groupTree = nsnull; - m_inhaled = PR_FALSE; - m_uniqueId = 0; - m_runningURL = runningURL; - m_block = nsnull; - m_groupFilePermissions = nsnull; - m_hostinfofilename = nsnull; - m_groupTreeDirty = 0; - return NS_OK; -} - -nsresult -nsNNTPHost::CleanUp() { - if (m_dirty) WriteNewsrc(); - if (m_groupTreeDirty) SaveHostInfo(); - PR_FREEIF(m_optionLines); - if (m_filename) delete [] m_filename; - if (m_hostname) delete [] m_hostname; - if (m_username) delete [] m_username; - NS_IF_RELEASE(m_groups); - NS_IF_RELEASE(m_newsgrouplists); - if (m_dbfilename) delete [] m_dbfilename; - delete m_groupTree; - if (m_block) delete [] m_block; -#ifdef UNREADY_CODE - if (m_groupFile) XP_FileClose (m_groupFile); -#endif - PR_FREEIF(m_groupFilePermissions); - if (M_FileOwner == this) M_FileOwner = nsnull; - PR_FREEIF(m_hostinfofilename); - PRInt32 i; - for (i = 0; i < m_supportedExtensions.Count(); i++) - PR_Free((char*) m_supportedExtensions[i]); - for (i = 0; i < m_searchableGroups.Count(); i++) - PR_Free((char*) m_searchableGroups[i]); - for (i = 0; i < m_searchableHeaders.Count(); i++) - PR_Free((char*) m_searchableHeaders[i]); - for (i = 0; i < m_propertiesForGet.Count(); i++) - PR_Free((char*) m_propertiesForGet[i]); - for (i = 0; i < m_valuesForGet.Count(); i++) - PR_Free((char*) m_valuesForGet[i]); - if (m_searchableGroupCharsets) - { - // We do NOT free the individual key/value pairs, - // because deleting m_searchableGroups above has - // already caused this to happen. - PL_HashTableDestroy(m_searchableGroupCharsets); - m_searchableGroupCharsets = nsnull; - } - return NS_OK; -} - - - -void -nsNNTPHost::OpenGroupFile(const PRIntn permissions) -{ -#ifdef UNREADY_CODE - NS_ASSERTION(permissions, "no permissions"); - if (!permissions) return; - if (m_groupFile) { - if (m_groupFilePermissions && - PL_strcmp(m_groupFilePermissions, permissions) == 0) { - return; - } - XP_FileClose(m_groupFile); - m_groupFile = nsnull; - } - if (M_FileOwner && M_FileOwner != this && M_FileOwner->m_groupFile) { - XP_FileClose(M_FileOwner->m_groupFile); - M_FileOwner->m_groupFile = nsnull; - } - M_FileOwner = this; - PR_FREEIF(m_groupFilePermissions); - m_groupFilePermissions = PL_strdup(permissions); - m_groupFile = XP_FileOpen(m_hostinfofilename, xpXoverCache, permissions); -#endif -} - - - -void nsNNTPHost::ClearNew() -{ - PRInt64 now = PR_Now(); - PRInt64 increment; - - LL_I2L(increment,1); - LL_ADD(m_firstnewdate,now,increment); -} - -nsresult -nsNNTPHost::WriteNewsrc() -{ - if (!m_groups) return NS_ERROR_NOT_INITIALIZED; -#ifdef UNREADY_CODE - NS_ASSERTON(m_dirty, "m_dirty is null"); - // Just to be sure. It's safest to go ahead and write it out anyway, - // even if we do somehow get called without the dirty bit set. - - XP_File fid=0; - - fid = XP_FileOpen(GetNewsrcFileName(), xpTemporaryNewsRC, - XP_FILE_WRITE_BIN); - - if (!fid) return MK_UNABLE_TO_OPEN_NEWSRC; - - PRInt32 status = 0; - -#if defined(XP_UNIX) || defined(XP_BEOS) - /* Clone the permissions of the "real" newsrc file into the temp file, - so that when we rename the finished temp file to the real file, the - preferences don't appear to change. */ - { - XP_StatStruct st; - - if (XP_Stat (GetNewsrcFileName(), &st, xpNewsRC) == 0) - /* Ignore errors; if it fails, bummer. */ - - /* SCO doesn't define fchmod at all. no big deal. - AIX3, however, defines it to take a char* as the first parameter. The - man page says it takes an int, though. ... */ -#if defined( SCO_SV ) || defined ( AIXV3 ) || defined(XP_BEOS) - { - char *really_tmp_file = WH_FileName(GetNewsrcFileName(), xpTemporaryNewsRC); - - chmod (really_tmp_file, (st.st_mode | S_IRUSR | S_IWUSR)); - - PR_Free(really_tmp_file); - } -#else - fchmod (fileno(fid), (st.st_mode | S_IRUSR | S_IWUSR)); -#endif - } -#endif /* XP_UNIX */ - - if (m_optionLines) { - status = XP_FileWrite(m_optionLines, PL_strlen(m_optionLines), fid); - if (status < ((PRInt32)PL_strlen(m_optionLines))) { - status = MK_MIME_ERROR_WRITING_FILE; - } - } - - PRInt32 n = m_groups->Count(); - for (PRInt32 i=0 ; i= 0 ; i++) { - nsresult rv; - nsINNTPNewsgroup* newsgroup = (nsINNTPNewsgroup*) ((*m_groups)[i]); - // GetNewsFolderInfo will get root category for cat container. -#ifdef HAVE_FOLDERINFO - char* str; - newsgroup->GetNewsFolderInfo()->GetSet()->Output(&str); -#else - char *str = nsnull; -#endif - if (!str) { - status = MK_OUT_OF_MEMORY; - break; - } - char *name=nsnull; - char *line; - rv = newsgroup->GetName(&name); - - PRBool isSubscribed=PR_FALSE; - rv = newsgroup->GetSubscribed(&isSubscribed); - line = PR_smprintf("%s%s %s" MSG_LINEBREAK, - name, - isSubscribed ? ":" : "!", str); - PR_FREEIF(name); - if (!line) { - delete [] str; - status = MK_OUT_OF_MEMORY; - break; - } - PRInt32 length = PL_strlen(line); - status = XP_FileWrite(line, length, fid); - if (status < length) { - status = MK_MIME_ERROR_WRITING_FILE; - } - delete [] str; - PR_Free(line); - } - - XP_FileClose(fid); - - if (status >= 0) { - if (XP_FileRename(GetNewsrcFileName(), xpTemporaryNewsRC, - GetNewsrcFileName(), xpNewsRC) < 0) - status = MK_MIME_ERROR_WRITING_FILE; - } - - if (status < 0) { - - XP_FileRemove(GetNewsrcFileName(), xpTemporaryNewsRC); - return status; - } - m_dirty = PR_FALSE; - if (m_writetimer) { -#ifdef UNREADY_CODE - FE_ClearTimeout(m_writetimer); -#endif - m_writetimer = nsnull; - } - - if (m_groupTreeDirty) SaveHostInfo(); - - return status; -#else - return 0; -#endif -} - - -nsresult -nsNNTPHost::WriteIfDirty() -{ - if (m_dirty) return WriteNewsrc(); - return NS_OK; -} - - -nsresult -nsNNTPHost::MarkDirty() -{ - m_dirty = PR_TRUE; -#ifdef UNREADY_CODE - if (!m_writetimer) - m_writetimer = FE_SetTimeout((TimeoutCallbackFunction)nsNNTPHost::WriteTimer, this, - 5L * 60L * 1000L); // Hard-coded -- 5 minutes. -#endif - return NS_OK; -} - -void -nsNNTPHost::WriteTimer(void* closure) -{ - nsNNTPHost* host = (nsNNTPHost*) closure; - host->m_writetimer = nsnull; - if (NS_FAILED(host->WriteNewsrc())) { - // ###tw Pop up error message??? - host->MarkDirty(); // Cause us to try again. Or is this bad? ###tw - } -} - - -nsresult -nsNNTPHost::SetNewsRCFilename(const char* name) -{ - delete [] m_filename; - m_filename = new char [PL_strlen(name) + 1]; - if (!m_filename) return NS_ERROR_OUT_OF_MEMORY; - PL_strcpy(m_filename, name); - - m_hostinfofilename = PR_smprintf("%s/hostinfo.dat", GetDBDirName()); - if (!m_hostinfofilename) return NS_ERROR_OUT_OF_MEMORY; -#ifdef UNREADY_CODE - XP_StatStruct st; - if (XP_Stat (m_hostinfofilename, &st, xpXoverCache) == 0) { - m_fileSize = st.st_size; - } - - if (m_groupFile) { - XP_FileClose(m_groupFile); - m_groupFile = nsnull; - } - - OpenGroupFile(); - - if (!m_groupFile) { - // It does not exist. Create an empty one. But first, we go through - // the whole directory and blow away anything that does not end in - // ".snm". This is to take care of people running B1 code, which - // kept databases with such filenames. - PRInt32 lastcount = -1; - PRInt32 count = -1; - do { - XP_Dir dir = XP_OpenDir(GetDBDirName(), xpXoverCache); - if (!dir) break; - lastcount = count; - count = 0; - XP_DirEntryStruct *entry = nsnull; - for (entry = XP_ReadDir(dir); entry; entry = XP_ReadDir(dir)) { - count++; - const char* name = entry->d_name; - PRInt32 length = PL_strlen(name); - if (name[0] == '.' || name[0] == '#' || - name[length - 1] == '~') continue; - if (length < 4 || - PL_strcasecmp(name + length - 4, ".snm") != 0) { - char* tmp = PR_smprintf("%s/%s", GetDBDirName(), name); - if (tmp) { - XP_FileRemove(tmp, xpXoverCache); - PR_Free(tmp); - } - } - } - XP_CloseDir(dir); - } while (lastcount != count); // Keep doing it over and over, until - // we get the same number of entries in - // the dir. This is because I do not - // trust XP_ReadDir() to do the right - // thing if I delete files out from - // under it. - - // OK, now create the new empty hostinfo file. - OpenGroupFile(XP_FILE_WRITE_BIN); - NS_ASSERTION(m_groupFile, "null ptr"); - if (!m_groupFile) - return NS_ERROR_NOT_INITIALIZED; - OpenGroupFile(); - NS_ASSERTION(m_groupFile, "null ptr"); - if (!m_groupFile) - return NS_ERROR_NOT_INITIALIZED; - - m_groupTreeDirty = 2; - } - - m_blockSize = 10240; // ###tw This really ought to be the most - // efficient file reading size for the current - // operating system. - - m_block = nsnull; - while (!m_block && (m_blockSize >= 512)) - { - m_block = new char[m_blockSize + 1]; - if (!m_block) - m_blockSize /= 2; - } - if (!m_block) - return MK_OUT_OF_MEMORY; - - m_groupTree = nsMsgGroupRecord::Create(nsnull, nsnull, 0, 0, 0); - if (!m_groupTree) - return MK_OUT_OF_MEMORY; - - return ReadInitialPart(); -#else - return NS_OK; -#endif -} - - -PRInt32 -nsNNTPHost::ReadInitialPart() -{ -#ifdef UNREADY_CODE - OpenGroupFile(); - if (!m_groupFile) return -1; - - PRInt32 length = XP_FileRead(m_block, m_blockSize, m_groupFile); - if (length < 0) length = 0; - m_block[length] = '\0'; - PRInt32 version = 0; - - char* ptr; - char* endptr = nsnull; - for (ptr = m_block ; *ptr ; ptr = endptr + 1) { - while (*ptr == CR || *ptr == LF) ptr++; - endptr = PL_strchr(ptr, LINEBREAK_START); - if (!endptr) break; - *endptr = '\0'; - if (ptr[0] == '#' || ptr[0] == '\0') { - continue; // Skip blank lines and comments. - } - if (PL_strcmp(ptr, "begingroups") == 0) { - m_fileStart = endptr - m_block; - break; - } - char* ptr2 = PL_strchr(ptr, '='); - if (!ptr2) continue; - *ptr2++ = '\0'; - if (PL_strcmp(ptr, "lastgroupdate") == 0) { - m_lastGroupUpdate = strtol(ptr2, nsnull, 16); - } else if (PL_strcmp(ptr, "firstnewdate") == 0) { - m_firstnewdate = strtol(ptr2, nsnull, 16); - } else if (PL_strcmp(ptr, "uniqueid") == 0) { - m_uniqueId = strtol(ptr2, nsnull, 16); - } else if (PL_strcmp(ptr, "pushauth") == 0) { - m_pushAuth = strtol(ptr2, nsnull, 16); - } else if (PL_strcmp(ptr, "version") == 0) { - version = strtol(ptr2, nsnull, 16); - } - } - m_block[0] = '\0'; - if (version != 1) { - // The file got clobbered or damaged somehow. Throw it away. -#ifdef DEBUG_NEWS - NS_ASSERTION(length <= 0, "length > 0"); -#endif - OpenGroupFile(XP_FILE_WRITE_BIN); - NS_ASSERTION(m_groupFile, "null ptr"); - if (!m_groupFile) return -1; - OpenGroupFile(); - NS_ASSERTION(m_groupFile, "null ptr"); - if (!m_groupFile) return -1; - - m_groupTreeDirty = 2; - m_fileStart = 0; - m_fileSize = 0; - } - m_groupTree->SetFileOffset(m_fileStart); -#endif - return 0; -} - -PRInt32 -nsNNTPHost::CreateFileHeader() -{ - PRInt32 firstnewdate; - - LL_L2I(firstnewdate, m_firstnewdate); - - PR_snprintf(m_block, m_blockSize, - "# News host information file." MSG_LINEBREAK - "# This is a generated file! Do not edit." MSG_LINEBREAK - "" MSG_LINEBREAK - "version=1" MSG_LINEBREAK - "newsrcname=%s" MSG_LINEBREAK -#ifdef OSF1 - "lastgroupdate=%08x" MSG_LINEBREAK - "firstnewdate=%08x" MSG_LINEBREAK - "uniqueid=%08x" MSG_LINEBREAK -#else - "lastgroupdate=%08lx" MSG_LINEBREAK - "firstnewdate=%08lx" MSG_LINEBREAK - "uniqueid=%08lx" MSG_LINEBREAK -#endif - "pushauth=%1x" MSG_LINEBREAK - "" MSG_LINEBREAK - "begingroups", - m_filename, m_lastGroupUpdate, firstnewdate, m_uniqueId, - m_pushAuth); - return PL_strlen(m_block); - -} - -PRInt32 -nsNNTPHost::SaveHostInfo() -{ - PRInt32 status = 0; -#ifdef UNREADY_CODE - nsMsgGroupRecord* grec; - XP_File in = nsnull; - XP_File out = nsnull; - char* blockcomma = nsnull; - char* ptrcomma = nsnull; - char* filename = nsnull; - PRInt32 length = CreateFileHeader(); - NS_ASSERTION(length < m_blockSize - 50, "length >= m_blockSize - 50"); - if (m_inhaled || length != m_fileStart) { - m_groupTreeDirty = 2; - } - if (m_groupTreeDirty < 0) { - // Uh, somehow we set the sign bit, probably some routine returned an - // error status. This will probably never happen. But if it does, - // we should just make sure to write things out in the most paranoid - // fashion. - m_groupTreeDirty = 2; - } - if (m_groupTreeDirty < 2) { - // Only bits and pieces are dirty. Write them out without writing the - // whole file. - OpenGroupFile(); - if (!m_groupFile) { - status = MK_UNABLE_TO_OPEN_NEWSRC; - goto FAIL; - } - XP_FileSeek(m_groupFile, 0, SEEK_SET); - XP_FileWrite(m_block, length, m_groupFile); - char* ptr = nsnull; - for (grec = m_groupTree->GetChildren(); - grec; - grec = grec->GetNextAlphabetic()) { - if (grec->IsDirty()) { - if (grec->GetFileOffset() < m_fileStart) { - m_groupTreeDirty = 2; - break; - } - ptr = grec->GetSaveString(); - if (!ptr) { - status = MK_OUT_OF_MEMORY; - goto FAIL; - } - length = PL_strlen(ptr); - if (length >= m_blockSize) { - char* tmp = new char [length + 512]; - if (!tmp) { - status = MK_OUT_OF_MEMORY; - goto FAIL; - } - delete [] m_block; - m_block = tmp; - m_blockSize = length + 512; - } - // Read the old data, and make sure the old line was the - // same length as the new one. If not, set the dirty flag - // to 2, so we end up writing the whole file, below. - XP_FileSeek(m_groupFile, grec->GetFileOffset(), SEEK_SET); - PRInt32 l = XP_FileRead(m_block, length, m_groupFile); - if (l != length || m_block[length - 1] != ptr[length - 1]) { - m_groupTreeDirty = 2; - break; - } - m_block[l] = '\0'; - char* p1 = PL_strchr(ptr, LINEBREAK_START); - char* p2 = PL_strchr(m_block, LINEBREAK_START); - NS_ASSERTION(p1,"null ptr"); - if (!p1 || !p2 || (p1 - ptr) != (p2 - m_block)) { - m_groupTreeDirty = 2; - break; - } - NS_ASSERTION(grec->GetFileOffset() > 100, "header is at least 100 bytes long"); - XP_FileSeek(m_groupFile, grec->GetFileOffset(), SEEK_SET); - XP_FileWrite(ptr, PL_strlen(ptr), m_groupFile); - PR_Free(ptr); - ptr = nsnull; - } - } - PR_FREEIF(ptr); - } - if (m_groupTreeDirty >= 2) { - // We need to rewrite the whole silly file. - filename = PR_smprintf("%s/tempinfo", GetDBDirName()); - if (!filename) return MK_OUT_OF_MEMORY; - PRInt32 position = 0; - - if (m_groupFile) - { - XP_FileClose(m_groupFile); - m_groupFile = nsnull; - } - - out = XP_FileOpen(filename, xpXoverCache, XP_FILE_WRITE_BIN); - if (!out) return MK_MIME_ERROR_WRITING_FILE; - - length = CreateFileHeader(); // someone probably has hosed m_block - so regen - status = XP_FileWrite(m_block, length, out); - if (status < 0) goto FAIL; - position += length; - m_fileStart = position; - m_groupTree->SetFileOffset(m_fileStart); - status = XP_FileWrite(MSG_LINEBREAK, MSG_LINEBREAK_LEN, out); - if (status < 0) goto FAIL; - position += MSG_LINEBREAK_LEN; - - blockcomma = nsnull; - if (!m_inhaled) { - in = XP_FileOpen(m_hostinfofilename, xpXoverCache, XP_FILE_READ); - if (!in) { - status = MK_MIME_ERROR_WRITING_FILE; - goto FAIL; - } - do { - m_block[0] = '\0'; - XP_FileReadLine(m_block, m_blockSize, in); - } while (m_block[0] && - PL_strncmp(m_block, "begingroups", 11) != 0); - m_block[0] = '\0'; - XP_FileReadLine(m_block, m_blockSize, in); - blockcomma = PL_strchr(m_block, ','); - if (blockcomma) *blockcomma = '\0'; - } - for (grec = m_groupTree->GetChildren(); - grec; - grec = grec->GetNextAlphabetic()) { - char* ptr = grec->GetSaveString(); - if (!ptr) { - status = MK_OUT_OF_MEMORY; - goto FAIL; - } - ptrcomma = PL_strchr(ptr, ','); - NS_ASSERTION(ptrcomma, "null ptr"); - if (!ptrcomma) { - status = -1; - goto FAIL; - } - *ptrcomma = '\0'; - while (blockcomma && - nsMsgGroupRecord::GroupNameCompare(m_block, ptr) < 0) { - *blockcomma = ','; - XP_StripLine(m_block); - length = PL_strlen(m_block); - status = XP_FileWrite(m_block, length, out); - if (status < 0) goto FAIL; - position += length; - status = XP_FileWrite(MSG_LINEBREAK, MSG_LINEBREAK_LEN, out); - if (status < 0) goto FAIL; - position += MSG_LINEBREAK_LEN; - m_block[0] = '\0'; - XP_FileReadLine(m_block, m_blockSize, in); - blockcomma = PL_strchr(m_block, ','); - if (blockcomma) *blockcomma = '\0'; - } - if (blockcomma && PL_strcmp(m_block, ptr) == 0) { - m_block[0] = '\0'; - XP_FileReadLine(m_block, m_blockSize, in); - blockcomma = PL_strchr(m_block, ','); - if (blockcomma) *blockcomma = '\0'; - } - grec->SetFileOffset(position); - *ptrcomma = ','; - length = PL_strlen(ptr); - // if the group doesn't exist on the server and has no children, - // don't write it out. - if (!grec->DoesNotExistOnServer() || grec->GetNumKids() > 0) - { - status = XP_FileWrite(ptr, length, out); - position += length; - } - else - status = 0; - PR_Free(ptr); - if (status < 0) goto FAIL; - } - if (blockcomma) { - *blockcomma = ','; - do { - XP_StripLine(m_block); - length = PL_strlen(m_block); - status = XP_FileWrite(m_block, length, out); - if (status < 0) goto FAIL; - position += length; - status = XP_FileWrite(MSG_LINEBREAK, MSG_LINEBREAK_LEN, out); - if (status < 0) goto FAIL; - position += MSG_LINEBREAK_LEN; - m_block[0] = '\0'; - } while (XP_FileReadLine(m_block, m_blockSize, in) && *m_block); - } - if (in) { - XP_FileClose(in); - in = nsnull; - } - XP_FileClose(out); - out = nsnull; - XP_FileRename(filename, xpXoverCache, - m_hostinfofilename, xpXoverCache); - m_fileSize = position; - } - m_groupTreeDirty = 0; - -FAIL: - if (in) XP_FileClose(in); - if (out) XP_FileClose(out); - if (filename) PR_Free(filename); - m_block[0] = '\0'; -#endif - return status; -} - - -struct InhaleState { - nsMsgGroupRecord* tree; - PRInt32 position; - nsMsgGroupRecord* onlyIfChild; - nsMsgGroupRecord* lastInhaled; - char lastfullname[512]; -}; - - -PRInt32 -nsNNTPHost::InhaleLine(char* line, PRUint32 length, void* closure) -{ - PRInt32 status = 0; - InhaleState* state = (InhaleState*) closure; - PRInt32 position = state->position; - state->position += length; - char* lastdot; - char* endptr = line + length; - char* comma; - for (comma = line ; comma < endptr ; comma++) { - if (*comma == ',') break; - } - if (comma >= endptr) return 0; - *comma = '\0'; - lastdot = PL_strrchr(line, '.'); - nsMsgGroupRecord* parent; - nsMsgGroupRecord* child; - if (lastdot) { - *lastdot = '\0'; - // Try to find the parent of this line. Very often, it will be - // the last line we read, or some ancestor of that line. - parent = nsnull; - if (state->lastInhaled && PL_strncmp(line, state->lastfullname, - lastdot - line) == 0) { - char c = state->lastfullname[lastdot - line]; - if (c == '\0') parent = state->lastInhaled; - else if (c == '.') { - parent = state->lastInhaled; - char* ptr = state->lastfullname + (lastdot - line); - NS_ASSERTION(parent, "null ptr"); - while (parent && ptr) { - parent = parent->GetParent(); - NS_ASSERTION(parent, "null ptr"); - if (parent) { - ptr = PL_strchr(ptr + 1, '.'); - } - else { - ptr = nsnull; - } - } - } - } - - - if (!parent) parent = state->tree->FindDescendant(line); - *lastdot = '.'; - NS_ASSERTION(parent, "null ptr"); - if (!parent) { - status = -1; - goto DONE; - } - } else { - parent = state->tree; - lastdot = line - 1; - } - child = parent->FindDescendant(lastdot + 1); - *comma = ','; - if (child) { - // It's already in memory. - child->SetFileOffset(position); - } else { - child = nsMsgGroupRecord::Create(parent, line, endptr - line, position); - if (!child) { - status = MK_OUT_OF_MEMORY; - goto DONE; - } - } - if (state->onlyIfChild) { - nsMsgGroupRecord* tmp; - for (tmp = child; tmp ; tmp = tmp->GetParent()) { - if (tmp == state->onlyIfChild) break; - } - if (tmp == nsnull) status = -2; // Indicates we're done. - } - NS_ASSERTION(comma - line < ((PRInt32)sizeof(state->lastfullname)), "unexpected"); - if ((comma - line)/sizeof(char) < sizeof(state->lastfullname)) { - PL_strncpyz(state->lastfullname, line, comma - line + 1); - state->lastfullname[comma - line] = '\0'; - state->lastInhaled = child; - } -DONE: - if (comma) *comma = ','; - return status; -} - - -PRInt32 -nsNNTPHost::Inhale(PRBool force) -{ -#ifdef UNREADY_CODE - if (m_groupTreeDirty) SaveHostInfo(); - if (force) { - while (m_groupTree->GetChildren()) { - delete m_groupTree->GetChildren(); - } - m_inhaled = PR_FALSE; - } - NS_ASSERTION(!m_inhaled, "m_inhaled is not null"); - if (m_inhaled) return -1; - PRInt32 status = 0; - OpenGroupFile(); - if (!m_groupFile) return -1; - XP_FileSeek(m_groupFile, 0, SEEK_SET); - status = ReadInitialPart(); - if (status < 0) return status; - XP_FileSeek(m_groupFile, m_fileStart, SEEK_SET); - InhaleState state; - state.tree = m_groupTree; - state.position = m_fileStart; - state.onlyIfChild = nsnull; - state.lastInhaled = nsnull; - char* buffer = nsnull; - PRUint32 buffer_size = 0; - PRUint32 buffer_fp = 0; - do { - status = XP_FileRead(m_block, m_blockSize, m_groupFile); - if (status <= 0) break; - status = msg_LineBuffer(m_block, status, - &buffer, &buffer_size, &buffer_fp, - PR_FALSE, -#ifdef XP_OS2 - (nsresult (_Optlink*) (char*,PRUint32,void*)) -#endif - nsNNTPHost::InhaleLine, &state); - } while (status >= 0); - if (status >= 0 && buffer_fp > 0) { - status = InhaleLine(buffer, buffer_fp, &state); - } - PR_FREEIF(buffer); - m_block[0] = '\0'; - if (status >= 0) m_inhaled = PR_TRUE; - return status; -#else - return 0; -#endif -} - - -PRInt32 -nsNNTPHost::Exhale() -{ - NS_ASSERTION(m_inhaled, "null ptr"); - if (!m_inhaled) return -1; - PRInt32 status = SaveHostInfo(); - while (m_groupTree->GetChildren()) { - delete m_groupTree->GetChildren(); - } - m_inhaled = PR_FALSE; - return status; -} - - -PRInt32 -nsNNTPHost::EmptyInhale() -{ - NS_ASSERTION(!m_inhaled, "m_inhaled is not null"); - if (m_inhaled) return -1; - while (m_groupTree->GetChildren()) { - delete m_groupTree->GetChildren(); - } - m_inhaled = PR_TRUE; - return 0; -} - - -nsresult -nsNNTPHost::FindGroup(const char* name, nsINNTPNewsgroup* *_retval) -{ - nsresult result = NS_ERROR_NOT_INITIALIZED; - - if (name == nsnull) { - return NS_ERROR_NULL_POINTER; - } -#ifdef DEBUG_NEWS - printf("FindGroup(%s)\n",name); -#endif - - if (!m_groups) return result; - PRUint32 cnt; - nsresult rv = m_groups->Count(&cnt); - if (NS_FAILED(rv)) return rv; - PRInt32 n = cnt; - for (PRInt32 i=0 ; iElementAt(i); - rv = info->GetName(&groupname); - -#ifdef DEBUG_NEWS - printf("%d = %s\n",i,groupname?groupname:"null"); -#endif - - if (NS_SUCCEEDED(rv) && (name != nsnull) && PL_strcmp(name, groupname) == 0) { - *_retval = info; - result = NS_OK; - } - PR_FREEIF(groupname); - } - return result; -} - -nsresult -nsNNTPHost::AddGroup(const char *name, - nsINNTPNewsgroup **_retval) -{ - return AddGroup(name, nsnull, _retval); -} - - -nsresult -nsNNTPHost::AddGroup(const char *name, - nsMsgGroupRecord *inGroupRecord, - nsINNTPNewsgroup **_retval) -{ -#ifdef DEBUG_NEWS - printf("nsNNTPHost::AddGroup(%s)\n",name); -#endif - nsINNTPNewsgroup *newsInfo = nsnull; - nsCOMPtr categoryContainer; - char* containerName = nsnull; - PRBool needpaneupdate = PR_FALSE; - PRBool isSubscribed=PR_FALSE; - - nsMsgGroupRecord* group = (inGroupRecord) ? inGroupRecord : FindOrCreateGroup(name); - if (!group) goto DONE; // Out of memory. - - if (!group->IsCategoryContainer() && group->IsCategory()) { - nsMsgGroupRecord *container = group->GetCategoryContainer(); - NS_ASSERTION(container,"null ptr"); - if (!container) goto DONE; - containerName = container->GetFullName(); - if (!containerName) goto DONE; // Out of memory. - - nsresult rv = FindGroup(containerName, &newsInfo); - - if (NS_SUCCEEDED(rv)) { - rv = newsInfo->QueryInterface(NS_GET_IID(nsINNTPCategoryContainer), - getter_AddRefs(categoryContainer)); - - // if we're not subscribed to container, do that instead. - if (NS_SUCCEEDED(rv)) - rv = newsInfo->GetSubscribed(&isSubscribed); - - if (NS_FAILED(rv) || !isSubscribed) - { - name = containerName; - group = FindOrCreateGroup(name); - } - NS_RELEASE(newsInfo); - // categoryContainer released at the end of this function - // (yuck) - } - } - - // no need to diddle folder pane for new categories. - needpaneupdate = m_hostinfo && !group->IsCategory(); - - nsresult rv; - rv = FindGroup(name, &newsInfo); - if (NS_SUCCEEDED(rv)) { // seems to be already added - PRBool subscribed; - rv = newsInfo->GetSubscribed(&subscribed); - if (NS_SUCCEEDED(rv) && !subscribed) { - newsInfo->SetSubscribed(PR_TRUE); - nsIMsgFolder *newsFolder = getFolderFor(newsInfo); - // m_hostinfo->AddSubfolderIfUnique(newsFolder); - m_hostinfo->AppendElement(newsFolder); - /* - nsISupportsArray* infolist; - nsresult rv = m_hostinfo->GetSubFolders(&infolist); - // don't add it if it's already in the list! - if (infolist->FindIndex(0, newsInfo) == -1) - infolist->Add(newsInfo); - */ - } else { - goto DONE; - } - } else { - char* groupLine = PR_smprintf("%s:", name); - if (!groupLine) { - goto DONE; // Out of memory. - } - -#if SETH_HACK - // this will add and auto-subscribe - OK, a cheap hack. - if (ProcessLine(groupLine, PL_strlen(groupLine)) == 0) { - - if (m_groups != nsnull) { - // groups are added at end so look there first... - PRUint32 cnt; - rv = m_groups->Count(&cnt); - if (NS_FAILED(rv)) return rv; - newsInfo = (nsINNTPNewsgroup *) - m_groups->ElementAt(cnt - 1); - } - - if (!newsInfo) goto DONE; - - char *name; - rv = newsInfo->GetName(&name); - if (NS_SUCCEEDED(rv) && - PL_strcmp(name, name)) { - rv = FindGroup(name, &newsInfo); - NS_ASSERTION(NS_SUCCEEDED(rv), "didn't find group"); - } - } -#else - NS_ASSERTION(0, "hacked up nsNNTPHost.cpp"); -#endif /* SETH_HACK */ - PR_Free(groupLine); - } - NS_ASSERTION(newsInfo, "null ptr"); - if (!newsInfo) goto DONE; - - if (group->IsCategoryContainer()) { - // Go add all of our categories to the newsrc. - AssureAllDescendentsLoaded(group); - nsMsgGroupRecord* end = group->GetSiblingOrAncestorSibling(); - nsMsgGroupRecord* child; - for (child = group->GetNextAlphabetic() ; - child != end ; - child = child->GetNextAlphabetic()) { - NS_ASSERTION(child, "null ptr"); - if (!child) break; - char* fullname = child->GetFullName(); - if (!fullname) break; - - nsINNTPNewsgroup* info; - - rv = FindGroup(fullname, &info); - if (NS_SUCCEEDED(rv)) { - PRBool subscribed; - rv = info->GetSubscribed(&subscribed); - if (NS_SUCCEEDED(rv) && !subscribed) { - info->SetSubscribed(PR_TRUE); - } - } else { - char* groupLine = PR_smprintf("%s:", fullname); - if (groupLine) { -#if SETH_HACK - ProcessLine(groupLine, PL_strlen(groupLine)); -#else - NS_ASSERTION(0, "hacked up nsNNTPHost.cpp"); -#endif /* SETH_HACK */ - PR_Free(groupLine); - } - } - delete [] fullname; - } - - // XXX ACK. This is hairy code. Fix this. - // solution: SwitchNewsToCategoryContainer should - // return an nsresult - nsINNTPCategoryContainer *catContainer; - rv = - newsInfo->QueryInterface(NS_GET_IID(nsINNTPCategoryContainer), - (void **)&catContainer); - if (NS_FAILED(rv)) - { - catContainer = SwitchNewsToCategoryContainer(newsInfo); - if (catContainer) rv = NS_OK; - } - NS_ASSERTION(NS_SUCCEEDED(rv), "failed to SwitchNewsToCategoryContainer"); - if (NS_SUCCEEDED(rv)) { - // XXX should this call be on catContainer or newsInfo? - nsIMsgFolder *folder = getFolderFor(newsInfo); - folder->SetFlag(MSG_FOLDER_FLAG_ELIDED); - NS_IF_RELEASE(folder); -#ifdef HAVE_MASTER - catContainer->BuildCategoryTree(catContainer, name, group, - ); -#endif - NS_RELEASE(catContainer); - } - } - else if (group->IsCategory() && categoryContainer) - { -#ifdef HAVE_MASTER - categoryContainer->AddToCategoryTree(categoryContainer, name, group, m_master); -#endif - } - -#ifdef HAVE_MASTER - if (needpaneupdate && newsInfo) - m_master->BroadcastFolderAdded (newsInfo); -#endif - - MarkDirty(); - -DONE: - - - if (containerName) delete [] containerName; - if (_retval) *_retval = newsInfo; - return NS_OK; -} - -nsINNTPCategoryContainer * -nsNNTPHost::SwitchNewsToCategoryContainer(nsINNTPNewsgroup *newsInfo) -{ - nsresult rv; - PRInt32 groupIndex = m_groups->IndexOf(newsInfo); - if (groupIndex != -1) - { - // create a category container to hold this newsgroup - nsINNTPCategoryContainer *newCatCont = nsnull; - // formerly newsInfo->CloneIntoCategoryContainer(); -#if 0 // not implemented yet - rv = nsComponentManager::CreateInstance(kNNTPCategoryContainerCID, nsnull, NS_GET_IID(nsINNTPCategoryContainer), getter_AddRefs(newCatCont)); - if (NS_FAILED(rv)) return nsnull; - - rv = newCatCont->Initialize(newsInfo); - if (NS_FAILED(rv)) return nsnull; -#endif - - // slip the category container where the newsInfo was. - m_groups->ReplaceElementAt(newCatCont, groupIndex); - - nsIMsgFolder *newsFolder = getFolderFor(newsInfo); - - rv = newsInfo->QueryInterface(NS_GET_IID(nsIMsgFolder), - (void **)&newsFolder); - if (newsFolder) { - nsIMsgFolder *catContFolder = getFolderFor(newCatCont); - if (catContFolder) { - m_hostinfo->ReplaceElement(newsFolder, catContFolder); - NS_RELEASE(catContFolder); - } - NS_RELEASE(newsFolder); - } - - /* - nsISupportsArray* infolist; - nsresult rv = m_hostinfo->GetSubFolders(&infolist); - // replace in folder pane server list as well. - groupIndex = infoList->FindIndex(0, newsInfo); - if (groupIndex != -1) - infoList->SetAt(groupIndex, newCatCont); - */ - return newCatCont; - } - // we used to just return newsInfo if groupIndex == -1 - // now we return nsnull and caller has to check for that. - return nsnull; -} - -nsINNTPNewsgroup * -nsNNTPHost::SwitchCategoryContainerToNews(nsINNTPCategoryContainer* - catContainerInfo) -{ - nsINNTPNewsgroup *retInfo = nsnull; - - PRInt32 groupIndex = m_groups->IndexOf(catContainerInfo); - if (groupIndex != -1) - { - nsINNTPNewsgroup *rootCategory; - catContainerInfo->GetRootCategory(&rootCategory); - // slip the root category container where the category container was. - m_groups->ReplaceElementAt(rootCategory, groupIndex); - - nsIMsgFolder *catContFolder = getFolderFor(catContainerInfo); - if (catContFolder) { - nsIMsgFolder *rootFolder = getFolderFor(rootCategory); - if (rootFolder) { - m_hostinfo->ReplaceElement(catContFolder, rootFolder); - NS_RELEASE(rootFolder); - } - NS_RELEASE(catContFolder); - } - /* - nsISupportsArray* infoList; - nsresult rv = m_hostinfo->GetSubFolders(&infoList); - // replace in folder pane server list as well. - groupIndex = infoList->FindIndex(0, catContainerInfo); - if (groupIndex != -1) - infoList->SetAt(groupIndex, rootCategory); - */ - retInfo = rootCategory; - // this effectively leaks the category container, but I don't think that's a problem - } - return retInfo; -} -nsresult -nsNNTPHost::RemoveGroup (nsINNTPNewsgroup *newsInfo) -{ - PRBool subscribed; - if (!newsInfo) return NS_ERROR_NULL_POINTER; - nsresult rv = ((nsINNTPNewsgroup *)newsInfo)->GetSubscribed(&subscribed); - if (NS_SUCCEEDED(rv) && subscribed) - { - ((nsINNTPNewsgroup *)newsInfo)->SetSubscribed(PR_FALSE); -#ifdef HAVE_MASTER - m_master->BroadcastFolderDeleted (newsInfo); -#endif - nsIMsgFolder* newsFolder = getFolderFor((nsINNTPNewsgroup*)newsInfo); - if (newsFolder) { - m_hostinfo->RemoveElement(newsFolder); - NS_RELEASE(newsFolder); - } - /* - nsISupportsArray* infolist; - nsresult rv = m_hostinfo->GetSubFolders(&infolist); - infolist->Remove(newsInfo); - */ - } - return NS_OK; -} - -nsresult -nsNNTPHost::RemoveGroupByName(const char* name) -{ - nsINNTPNewsgroup *newsInfo = nsnull; - - nsresult rv = FindGroup(name, &newsInfo); - if (NS_SUCCEEDED(rv)) - RemoveGroup (newsInfo); - - return NS_OK; -} - - -#ifdef DEBUG_terry -// #define XP_WIN16 -#endif - -const char* -nsNNTPHost::GetDBDirName() -{ - if (!m_filename) return nsnull; - if (!m_dbfilename) { -#if defined(XP_WIN16) || defined(XP_OS2) - const PRInt32 MAX_HOST_NAME_LEN = 8; -#elif defined(XP_MAC) - const PRInt32 MAX_HOST_NAME_LEN = 25; -#else - const PRInt32 MAX_HOST_NAME_LEN = 55; -#endif - // Given a hostname, use either that hostname, if it fits on our - // filesystem, or a hashified version of it, if the hostname is too - // long to fit. - char hashedname[MAX_HOST_NAME_LEN + 1]; - PRBool needshash = (((PRInt32)PL_strlen(m_filename)) > MAX_HOST_NAME_LEN); -#if defined(XP_WIN16) || defined(XP_OS2) - if (!needshash) { - needshash = PL_strchr(m_filename, '.') != nsnull || - PL_strchr(m_filename, ':') != nsnull; - } -#endif - - PL_strncpyz(hashedname, m_filename, MAX_HOST_NAME_LEN + 1); - if (needshash) { - PR_snprintf(hashedname + MAX_HOST_NAME_LEN - 8, 9, "%08lx", - (unsigned long) PL_HashString(m_filename)); - } - m_dbfilename = new char [PL_strlen(hashedname) + 15]; -#if defined(XP_WIN16) || defined(XP_OS2) - PL_strcpy(m_dbfilename, hashedname); - PL_strcat(m_dbfilename, ".dir"); -#else - PL_strcpy(m_dbfilename, "host-"); - PL_strcat(m_dbfilename, hashedname); - char* ptr = PL_strchr(m_dbfilename, ':'); - if (ptr) *ptr = '.'; // Windows doesn't like colons in filenames. -#endif - -#ifdef UNREADY_CODE - XP_MakeDirectory(m_dbfilename, xpXoverCache); -#endif - } - return m_dbfilename; -} - - -nsresult -nsNNTPHost::GetNumGroupsNeedingCounts(PRInt32 *value) -{ - if (!m_groups) return NS_ERROR_NOT_INITIALIZED; - PRUint32 cnt; - nsresult rv = m_groups->Count(&cnt); - if (NS_FAILED(rv)) return rv; - PRInt32 num = cnt; - PRInt32 result = 0; - for (PRInt32 i=0 ; iElementAt(i); - PRBool wantNewTotals, subscribed; - rv = info->GetWantNewTotals(&wantNewTotals); - if (NS_SUCCEEDED(rv)) - rv = info->GetSubscribed(&subscribed); - if (NS_SUCCEEDED(rv) && - wantNewTotals && - subscribed) { - result++; - } - } - *value = result; - // return rv; ?? - return NS_OK; -} - -nsresult -nsNNTPHost::GetFirstGroupNeedingCounts(char **result) -{ - if (!m_groups) return NS_ERROR_NULL_POINTER; - PRUint32 cnt; - nsresult rv = m_groups->Count(&cnt); - if (NS_FAILED(rv)) return rv; - PRInt32 num = cnt; - for (PRInt32 i=0 ; iElementAt(i); - - PRBool wantNewTotals, subscribed; - rv = info->GetWantNewTotals(&wantNewTotals); - if (NS_SUCCEEDED(rv)) - rv = info->GetSubscribed(&subscribed); - - if (NS_SUCCEEDED(rv) && - wantNewTotals && - subscribed) { - info->SetWantNewTotals(PR_FALSE); - char *name; - rv = info->GetName(&name); - if (NS_SUCCEEDED(rv)) { - // don't need to dup because GetName makes a copy - *result = name; - return NS_OK; - } - } - } - *result = nsnull; - // return rv; ?? - return NS_OK; -} - - -nsresult -nsNNTPHost::GetFirstGroupNeedingExtraInfo(char **result) -{ - nsMsgGroupRecord* grec = nsnull; - - *result=nsnull; - for (grec = m_groupTree->GetChildren(); grec; grec = grec->GetNextAlphabetic()) { - if (grec && grec->NeedsExtraInfo()) { - char *fullName = grec->GetFullName(); - *result = PL_strdup(fullName); - delete [] fullName; - return NS_OK; - } - } - return NS_OK; -} - - - -void -nsNNTPHost::SetWantNewTotals(PRBool value) -{ - if (!m_groups) return; - PRUint32 cnt; - nsresult rv = m_groups->Count(&cnt); - if (NS_FAILED(rv)) return; // XXX error? - PRInt32 n = cnt; - for (PRInt32 i=0 ; iElementAt(i); - info->SetWantNewTotals(value); - } -} - - - -PRBool nsNNTPHost::NeedsExtension (const char * /*extension*/) -{ - //###phil need to flesh this out - PRBool needed = m_supportsExtensions; - return needed; -} - -nsresult -nsNNTPHost::AddExtension (const char *ext) -{ - PRBool alreadyHasExtension=PR_FALSE; - QueryExtension(ext, &alreadyHasExtension); - if (!alreadyHasExtension) - { - char *ourExt = PL_strdup (ext); - if (ourExt) - m_supportedExtensions.AppendElement(ourExt); - } - return NS_OK; -} - -nsresult -nsNNTPHost::QueryExtension (const char *ext, PRBool *_retval) -{ - *_retval = PR_FALSE; - for (PRInt32 i = 0; i < m_supportedExtensions.Count(); i++) - if (!PL_strcmp(ext, (char*) m_supportedExtensions[i])) { - *_retval=PR_TRUE; - return NS_OK; - } - return NS_OK; -} - -nsresult -nsNNTPHost::AddSearchableGroup (const char *group) -{ - PRBool searchableGroup; - nsresult rv = QuerySearchableGroup(group, &searchableGroup); - if (NS_SUCCEEDED(rv) && !searchableGroup) - { - char *ourGroup = PL_strdup (group); - if (ourGroup) - { - // strip off character set spec - char *space = PL_strchr(ourGroup, ' '); - if (space) - *space = '\0'; - - m_searchableGroups.AppendElement(ourGroup); - - space++; // walk over to the start of the charsets - // Add the group -> charset association. - PL_HashTableAdd(m_searchableGroupCharsets, ourGroup, space); - } - } - return NS_OK; -} - -nsresult -nsNNTPHost::QuerySearchableGroup (const char *group, PRBool *_retval) -{ - *_retval = PR_FALSE; - for (PRInt32 i = 0; i < m_searchableGroups.Count(); i++) - { - const char *searchableGroup = (const char*) m_searchableGroups[i]; - char *starInSearchableGroup = nsnull; - - if (!PL_strcmp(searchableGroup, "*")) { - *_retval = PR_TRUE; // everything is searchable - return NS_OK; - } - else if (nsnull != (starInSearchableGroup = PL_strchr(searchableGroup, '*'))) - { - if (!PL_strncasecmp(group, searchableGroup, PL_strlen(searchableGroup)-2)) { - *_retval = PR_TRUE; // this group is in a searchable hierarchy - return NS_OK; - } - } - else if (!PL_strcasecmp(group, searchableGroup)) { - *_retval = PR_TRUE; // this group is individually searchable - return NS_OK; - } - } - return NS_OK; -} - -// ### mwelch This should have been merged into one routine with QuerySearchableGroup, -// but with two interfaces. -nsresult -nsNNTPHost::QuerySearchableGroupCharsets(const char *group, char **result) -{ - // Very similar to the above, but this time we look up charsets. - PRBool gotGroup = PR_FALSE; - const char *searchableGroup = nsnull; - *result = nsnull; - - for (PRInt32 i = 0; (i < m_searchableGroups.Count()) && (!gotGroup); i++) - { - searchableGroup = (const char*) m_searchableGroups[i]; - char *starInSearchableGroup = nsnull; - - if (!PL_strcmp(searchableGroup, "*")) - gotGroup = PR_TRUE; // everything is searchable - else if (nsnull != (starInSearchableGroup = PL_strchr(searchableGroup, '*'))) - { - if (!PL_strncasecmp(group, searchableGroup, PL_strlen(searchableGroup)-2)) - gotGroup = PR_TRUE; // this group is in a searchable hierarchy - } - else if (!PL_strcasecmp(group, searchableGroup)) - gotGroup = PR_TRUE; // this group is individually searchable - } - - if (gotGroup) - { - // Look up the searchable group for its supported charsets - *result = (char *) PL_HashTableLookup(m_searchableGroupCharsets, searchableGroup); - } - - return NS_OK; -} - -nsresult -nsNNTPHost::AddSearchableHeader (const char *header) -{ - PRBool searchable; - nsresult rv = QuerySearchableHeader(header, &searchable); - if (NS_SUCCEEDED(rv) && searchable) - { - char *ourHeader = PL_strdup(header); - if (ourHeader) - m_searchableHeaders.AppendElement(ourHeader); - } - return NS_OK; -} - -nsresult -nsNNTPHost::QuerySearchableHeader(const char *header, PRBool *_retval) -{ - *_retval=PR_FALSE; - for (PRInt32 i = 0; i < m_searchableHeaders.Count(); i++) - if (!PL_strncasecmp(header, (char*) m_searchableHeaders[i], PL_strlen(header))) { - *_retval = PR_TRUE; - return NS_OK; - } - return NS_OK; -} - -nsresult -nsNNTPHost::AddPropertyForGet (const char *property, const char *value) -{ - char *tmp = nsnull; - - tmp = PL_strdup(property); - if (tmp) - m_propertiesForGet.AppendElement(tmp); - - tmp = PL_strdup(value); - if (tmp) - m_valuesForGet.AppendElement(tmp); - - // this is odd. do we need this return value? - return NS_OK; -} - -nsresult -nsNNTPHost::QueryPropertyForGet (const char *property, char **_retval) -{ - *_retval=nsnull; - for (PRInt32 i = 0; i < m_propertiesForGet.Count(); i++) - if (!PL_strcasecmp(property, (const char *) m_propertiesForGet[i])) { - *_retval = (char *)m_valuesForGet[i]; - return NS_OK; - } - - return NS_OK; -} - - -nsresult -nsNNTPHost::SetPushAuth(PRBool value) -{ - if (m_pushAuth != value) - { - m_pushAuth = value; - m_groupTreeDirty |= 1; - } - return NS_OK; -} - -PRInt32 nsNNTPHost::RemoveHost() -{ -#ifdef UNREADY_CODE - if (m_groupFile) { - XP_FileClose(m_groupFile); - m_groupFile = nsnull; - } - m_dirty = 0; - if (m_writetimer) { -#ifdef UNREADY_CODE - FE_ClearTimeout(m_writetimer); -#endif - m_writetimer = nsnull; - } - - // Tell netlib to close any connections we might have to this news host. - NET_OnNewsHostDeleted (m_hostname); - - // Delete disk storage for summary files etc. - // Use notifications through the master to prevent the folder pane - // from loading anything while we're deleting all the newsgroups. -#ifdef HAVE_MASTER - m_master->BroadcastBeginDeletingHost (m_hostinfo); - nsIMsgFolder *tree = m_master->GetFolderTree(); - rv = tree->PropagateDelete(&m_hostinfo, PR_TRUE /*deleteStorage*/); - - // Here's a little hack to work around the fact that the FE may be holding - // a newsgroup open, and part of the delete might have failed. The WinFE does - // this when you delete a news server from the prefs - if (NS_SUCCEEDED(rv) && m_hostinfo) - { - m_master->BroadcastFolderDeleted (m_hostinfo); - tree->RemoveSubFolder (m_hostinfo); - } - m_master->BroadcastEndDeletingHost (m_hostinfo); - - m_master->GetHostTable()->RemoveEntry(this); -#endif - // XXX And what are we supposed to be doing here? Do we keep - // a reference to ourselves? - // maybe NS_RELEASE(this); ? -#if 0 - delete this; -#endif -#endif - - return 0; -} - - - -char* -nsNNTPHost::GetPrettyName(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (group) { - const char* orig = group->GetPrettyName(); - if (orig) { - char* result = new char [PL_strlen(orig) + 1]; - if (result) { - PL_strcpy(result, orig); - return result; - } - } - } - return nsnull; -} - - -nsresult -nsNNTPHost::SetPrettyName(const char* name, const char* prettyname) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = group->SetPrettyName(prettyname); - if (NS_FAILED(rv)) - { - nsINNTPNewsgroup *newsFolder; - rv = FindGroup(name, &newsFolder); - // make news folder forget prettyname so it will query again - if (NS_SUCCEEDED(rv) && newsFolder) - newsFolder->SetPrettyName(nsnull); - } - - // this used to say - // m_groupTreeDirty |= status; - // where status came from the previous SetPrettyName - if (NS_SUCCEEDED(rv)) m_groupTreeDirty |= 1; - return rv; -} - - -PRTime -nsNNTPHost::GetAddTime(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return LL_ZERO; - return group->GetAddTime(); -} - - -PRInt32 -nsNNTPHost::GetUniqueID(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return 0; - return group->GetUniqueID(); -} - - -PRBool -nsNNTPHost::IsCategory(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return PR_FALSE; - return group->IsCategory(); -} - - -PRBool -nsNNTPHost::IsCategoryContainer(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return PR_FALSE; - return group->IsCategoryContainer(); -} - -PRInt32 -nsNNTPHost::SetIsCategoryContainer(const char* name, PRBool value, nsMsgGroupRecord *inGroupRecord) -{ - nsresult rv; - nsMsgGroupRecord* group = (inGroupRecord) ? inGroupRecord : FindOrCreateGroup(name); - if (!group) return MK_OUT_OF_MEMORY; - PRInt32 status = group->SetIsCategoryContainer(value); - m_groupTreeDirty |= status; - if (status > 0) - { - nsINNTPNewsgroup *newsgroup; - rv = FindGroup(name, &newsgroup); - - nsIMsgFolder *newsFolder = getFolderFor(newsgroup); - - // make news folder have correct category container flag - if (NS_SUCCEEDED(rv) && newsgroup) - { - if (value) - { - // change newsgroup into a category container - newsFolder->SetFlag(MSG_FOLDER_FLAG_CAT_CONTAINER); - SwitchNewsToCategoryContainer(newsgroup); - } - else - { - // change category container into a newsgroup - nsINNTPCategoryContainer *catCont; - rv = newsgroup->QueryInterface(NS_GET_IID(nsINNTPCategoryContainer), - (void **)&catCont); - - if (NS_SUCCEEDED(rv)) - { - // release the old newsgroup/newsfolder and get - // the converted one instead - NS_IF_RELEASE(newsgroup); - newsgroup = SwitchCategoryContainerToNews(catCont); - NS_RELEASE(catCont); - - // make sure newsFolder is in sync with newsgroup - NS_IF_RELEASE(newsFolder); - newsFolder = getFolderFor(newsgroup); - - } - - if (newsFolder) - { - newsFolder->ClearFlag(MSG_FOLDER_FLAG_CAT_CONTAINER); - newsFolder->ClearFlag(MSG_FOLDER_FLAG_CATEGORY); - } - } - NS_RELEASE(newsFolder); - NS_RELEASE(newsgroup); - } - } - return status; -} - -nsresult -nsNNTPHost::SetGroupNeedsExtraInfo(const char *name, PRBool value) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = group->SetNeedsExtraInfo(value); - if (NS_SUCCEEDED(rv)) m_groupTreeDirty |= 1; - return rv; -} - - -char* -nsNNTPHost::GetCategoryContainer(const char* name, nsMsgGroupRecord *inGroupRecord) -{ - nsMsgGroupRecord* group = (inGroupRecord) ? inGroupRecord : FindOrCreateGroup(name); - if (group) { - group = group->GetCategoryContainer(); - if (group) return group->GetFullName(); - } - return nsnull; -} - -nsINNTPNewsgroup * -nsNNTPHost::GetCategoryContainerFolderInfo(const char *name) -{ - nsINNTPNewsgroup *newsgroup=nsnull; - nsresult rv; - // because GetCategoryContainer returns nsnull for a category container... - nsMsgGroupRecord *group = FindOrCreateGroup(name); - if (group->IsCategoryContainer()) { - rv = FindGroup(name, &newsgroup); - if (NS_SUCCEEDED(rv)) return newsgroup; - else return nsnull; - } - - char *categoryContainerName = GetCategoryContainer(name); - if (categoryContainerName) - { - rv = FindGroup(categoryContainerName, &newsgroup); - delete [] categoryContainerName; - } - return newsgroup; -} - - -nsresult -nsNNTPHost::GetIsVirtualGroup(const char* name, PRBool *_retval) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) { - *_retval = PR_FALSE; - return NS_OK; - } - else - return group->IsVirtual(_retval); -} - - -nsresult -nsNNTPHost::SetIsVirtualGroup(const char* name, PRBool value) -{ - return SetIsVirtualGroup(name, value, nsnull); -} -nsresult -nsNNTPHost::SetIsVirtualGroup(const char* name, PRBool value, - nsMsgGroupRecord* inGroupRecord) -{ - nsMsgGroupRecord* group = (inGroupRecord) ? inGroupRecord : FindOrCreateGroup(name); - - if (!group) return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv = group->SetIsVirtual(value); - if (NS_SUCCEEDED(rv)) m_groupTreeDirty |= 1; - return rv; -} - - - -PRBool -nsNNTPHost::IsGroup(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return PR_FALSE; - return group->IsGroup(); -} - - -PRInt32 -nsNNTPHost::SetIsGroup(char* name, PRBool value) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return MK_OUT_OF_MEMORY; - PRInt32 status = group->SetIsGroup(value); - m_groupTreeDirty |= status; - return status; -} - - -PRBool -nsNNTPHost::IsHTMLOk(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return PR_FALSE; - if (group->IsHTMLOKGroup()) return PR_TRUE; - for ( ; group ; group = group->GetParent()) { - if (group->IsHTMLOKTree()) return PR_TRUE; - } - return PR_FALSE; -} - - -PRBool -nsNNTPHost::IsHTMLOKGroup(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return PR_FALSE; - return group->IsHTMLOKGroup(); -} - - -PRInt32 -nsNNTPHost::SetIsHTMLOKGroup(char* name, PRBool value) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return MK_OUT_OF_MEMORY; - PRInt32 status = group->SetIsHTMLOKGroup(value); - m_groupTreeDirty |= status; - return status; -} - - -PRBool -nsNNTPHost::IsHTMLOKTree(char* name) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return PR_FALSE; - return group->IsHTMLOKTree(); -} - - -PRInt32 -nsNNTPHost::SetIsHTMLOKTree(char* name, PRBool value) -{ - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (!group) return MK_OUT_OF_MEMORY; - PRInt32 status = group->SetIsHTMLOKTree(value); - m_groupTreeDirty |= status; - return status; -} - -nsMsgGroupRecord* -nsNNTPHost::FindGroupInBlock(nsMsgGroupRecord* parent, - char* name, - PRInt32* comp) -{ -#ifdef UNREADY_CODE - char* ptr; - char* ptr2; - char* tmp; -RESTART: - ptr = m_block; - *comp = 0; - for (;;) { - ptr = PL_strchr(ptr, LINEBREAK_START); - ptr2 = ptr ? PL_strchr(ptr, ',') : 0; - if (!ptr2) { - if (*comp != 0) return nsnull; - // Yikes. The whole string, and we can't even find a legitimate - // beginning of a real line. Grow the buffer until we can. - - if (m_fileSize - m_fileStart <= m_blockSize) { - // Oh, well, maybe the file is just empty. Fine. - *comp = 0; - return nsnull; - } - - if (PRInt32(PL_strlen(m_block)) < m_blockSize) goto RELOAD; - goto GROWBUFFER; - } - while (*ptr == CR || *ptr == LF) ptr++; - *ptr2 = '\0'; - PRInt32 c = nsMsgGroupRecord::nameCompare(name, ptr); - *ptr2 = ','; - if (c < 0) { - if (*comp > 0) { - // This group isn't in the file, since earlier compares said - // "look later" and this one says "look earlier". - *comp = 0; - return nsnull; - } - *comp = c; - return nsnull; // This group is somewhere before this chunk. - } - *comp = c; - if (c == 0) { - // Hey look, we found it. - PRInt32 offset = m_blockStart + (ptr - m_block); - ptr2 = PL_strchr(ptr2, LINEBREAK_START); - if (!ptr2) { - // What a pain. We found the right place, but the rest of - // the line is off the end of the buffer. - if (offset > m_blockStart + MSG_LINEBREAK_LEN) { - m_blockStart = offset - MSG_LINEBREAK_LEN; - goto RELOAD; - } - // We couldn't find it, even though we're at the beginning - // of the buffer. This means that our buffer is too small. - // Bleah. - - goto GROWBUFFER; - } - return nsMsgGroupRecord::Create(parent, ptr, -1, offset); - } - } - /* NOTREACHED */ - return nsnull; - -GROWBUFFER: - - tmp = new char [m_blockSize + 512 + 1]; - if (!tmp) return nsnull; - delete [] m_block; - m_block = tmp; - m_blockSize += 512; - -RELOAD: - if (m_blockStart + m_blockSize > m_fileSize) { - m_blockStart = m_fileSize - m_blockSize; - if (m_blockStart < m_fileStart) m_blockStart = m_fileStart; - } - - OpenGroupFile(); - if (!m_groupFile) return nsnull; - XP_FileSeek(m_groupFile, m_blockStart, SEEK_SET); - PRInt32 length = XP_FileRead(m_block, m_blockSize, m_groupFile); - if (length < 0) length = 0; - m_block[length] = '\0'; - goto RESTART; -#else - return nsnull; -#endif -} - - -nsMsgGroupRecord* -nsNNTPHost::LoadSingleEntry(nsMsgGroupRecord* parent, char* name, - PRInt32 min, PRInt32 max) -{ -#ifdef UNREADY_CODE - OpenGroupFile(); - if (!m_groupFile) return nsnull; - -#ifdef DEBUG_NEWS - if (parent != m_groupTree) { - char* pname = parent->GetFullName(); - if (pname) { - NS_ASSERTION(PL_strncmp(pname, name, PL_strlen(pname)) == 0, "pname != name"); - delete [] pname; - pname = nsnull; - } - } -#endif /* DEBUG_NEWS */ - - if (min < m_fileStart) min = m_fileStart; - if (max < m_fileStart || max > m_fileSize) max = m_fileSize; - - nsMsgGroupRecord* result = nsnull; - PRInt32 comp = 1; - - // First, check if we happen to already have the line for this group in - // memory. - if (m_block[0]) { - result = FindGroupInBlock(parent, name, &comp); - } - - while (!result && comp != 0 && min < max) { - PRInt32 mid = (min + max) / 2; - m_blockStart = mid - MSG_LINEBREAK_LEN; - XP_FileSeek(m_groupFile, m_blockStart, SEEK_SET); - PRInt32 length = XP_FileRead(m_block, m_blockSize, m_groupFile); - if (length < 0) length = 0; - m_block[length] = '\0'; - - result = FindGroupInBlock(parent, name, &comp); - - if (comp > 0) { - min = mid + 1; - } else { - max = mid; - } - } - return result; -#else - return 0; -#endif /* UNREADY_CODE */ -} - - -nsMsgGroupRecord* -nsNNTPHost::FindOrCreateGroup(const char* name, - int* statusOfMakingGroup) -{ - char buf[256]; - - nsMsgGroupRecord* parent = m_groupTree; - const char* start = name; - NS_ASSERTION(start && *start, "name was bad"); - if (!start || !*start) return nsnull; - - NS_ASSERTION(*start != '.', "names can't start with ."); - if (*start == '.') return nsnull; - - while (*start) - { - if (*start == '.') start++; - const char* end = PL_strchr(start, '.'); - if (!end) end = start + PL_strlen(start); - PRInt32 length = end - start; - NS_ASSERTION(length > 0, "names can't contain .. or end in ."); - if (length <= 0) return nsnull; - NS_ASSERTION((PRUint32)length < sizeof(buf), "bad length"); - if ((PRUint32)length >= sizeof(buf)) return nsnull; - PL_strncpyz(buf, start, length + 1); - buf[length] = '\0'; - - nsMsgGroupRecord* prev = parent; - nsMsgGroupRecord* ptr = nsnull; - PRInt32 comp = 0; // Initializing to zero. - if (parent) - { - for (ptr = parent->GetChildren() ; ptr ; ptr = ptr->GetSibling()) - { - comp = nsMsgGroupRecord::GroupNameCompare(ptr->GetPartName(), buf); - if (comp >= 0) - break; - prev = ptr; - } - } - - if (ptr == nsnull || comp != 0) - { - // We don't have this one in memory. See if we can load it in. - if (!m_inhaled && parent) - { - if (ptr == nsnull) - { - ptr = parent->GetSiblingOrAncestorSibling(); - } - length = end - name; - char* tmp = new char[length + 1]; - if (!tmp) return nsnull; - PL_strncpyz(tmp, name, length + 1); - tmp[length] = '\0'; - ptr = LoadSingleEntry(parent, tmp, - prev->GetFileOffset(), - ptr ? ptr->GetFileOffset() : m_fileSize); - delete [] tmp; - tmp = nsnull; - } - else - { - ptr = nsnull; - } - - if (!ptr) - { - m_groupTreeDirty = 2; - ptr = nsMsgGroupRecord::Create(parent, buf, PR_Now(), - m_uniqueId++, 0); - if (!ptr) return nsnull; - } - } - parent = ptr; - start = end; - } - PRInt32 status = parent->SetIsGroup(PR_TRUE); - m_groupTreeDirty |= status; - if (statusOfMakingGroup) *statusOfMakingGroup = status; - return parent; -} - - -PRInt32 -nsNNTPHost::NoticeNewGroup(const char* name, nsMsgGroupRecord **outGroupRecord) -{ - PRInt32 status = 0; - nsMsgGroupRecord* group = FindOrCreateGroup(name, &status); - if (!group) return MK_OUT_OF_MEMORY; - if (outGroupRecord) - *outGroupRecord = group; - return status; -} - - -PRInt32 -nsNNTPHost::AssureAllDescendentsLoaded(nsMsgGroupRecord* group) -{ -#ifdef UNREADY_CODE - PRInt32 status = 0; - NS_ASSERTION(group, "null ptr"); - if (!group) return -1; - if (group->IsDescendentsLoaded()) return 0; - m_blockStart = group->GetFileOffset(); - NS_ASSERTION(group->GetFileOffset() > 0, "bad offset"); - if (group->GetFileOffset() == 0) return -1; - InhaleState state; - state.tree = m_groupTree; - state.position = m_blockStart; - state.onlyIfChild = group; - state.lastInhaled = nsnull; - OpenGroupFile(); - NS_ASSERTION(m_groupFile, "null ptr"); - if (!m_groupFile) return -1; - XP_FileSeek(m_groupFile, group->GetFileOffset(), SEEK_SET); - char* buffer = nsnull; - PRUint32 buffer_size = 0; - PRUint32 buffer_fp = 0; - do { - status = XP_FileRead(m_block, m_blockSize, m_groupFile); - if (status <= 0) break; - status = msg_LineBuffer(m_block, status, - &buffer, &buffer_size, &buffer_fp, - PR_FALSE, -#ifdef XP_OS2 - (nsresult (_Optlink*) (char*,PRUint32,void*)) -#endif - nsNNTPHost::InhaleLine, &state); - } while (status >= 0); - if (status >= 0 && buffer_fp > 0) { - status = InhaleLine(buffer, buffer_fp, &state); - } - if (status == -2) status = 0; // Special status meaning we ran out of - // lines that are children of the given - // group. - - PR_FREEIF(buffer); - m_block[0] = '\0'; - - if (status >= 0) group->SetIsDescendentsLoaded(PR_TRUE); - return status; -#else - return 0; -#endif -} - -nsresult -nsNNTPHost::GroupNotFound(const char *name, PRBool opening) -{ - // if no group command has succeeded, don't blow away categories. - // The server might be wedged... - if (!opening && !m_groupSucceeded) - return NS_ERROR_NOT_INITIALIZED; - - nsresult rv; - nsMsgGroupRecord* group = FindOrCreateGroup(name); - if (group && (group->IsCategory() || opening)) - { - nsINNTPNewsgroup *newsInfo = nsnull; - nsIMsgFolder *newsFolder = nsnull; - - // get the group and corresponding folder - rv = FindGroup(name, &newsInfo); - if (NS_SUCCEEDED(rv)) - newsFolder = getFolderFor(newsInfo); - - group->SetDoesNotExistOnServer(PR_TRUE); - m_groupTreeDirty |= 2; // deleting a group has to force a rewrite anyway - if (group->IsCategory()) - { - nsINNTPNewsgroup *catCont = GetCategoryContainerFolderInfo(name); - if (catCont) - { - nsIMsgFolder *catFolder = getFolderFor(catCont); - if (catFolder) { - - nsCOMPtr parentCategory; - rv = newsFolder->GetParent(getter_AddRefs(parentCategory)); - if (NS_SUCCEEDED(rv)) { - parentCategory->RemoveElement(newsFolder); - } - NS_RELEASE(catFolder); - } - } - } -#ifdef HAVE_MASTER - else if (newsInfo) { - m_master->BroadcastFolderDeleted (newsInfo); - } -#endif - if (newsInfo) - { - m_hostinfo->RemoveElement(newsFolder); - /* - nsISupportsArray* infolist; - nsresult rv = m_hostinfo->GetSubFolders(&infolist); - infolist->Remove(newsInfo); - */ - m_groups->RemoveElement(newsInfo); - m_dirty = PR_TRUE; - NS_RELEASE(newsInfo); - NS_IF_RELEASE(newsFolder); - } - } - return NS_OK; -} - - -PRInt32 -nsNNTPHost::ReorderGroup(nsINNTPNewsgroup *groupToMove, nsINNTPNewsgroup *groupToMoveBefore, PRInt32 *newIdx) -{ - // Do the list maintenance to reorder a newsgroup. The news host has a list, and - // so does the FolderInfo which represents the host in the hierarchy tree - - PRInt32 err = MK_MSG_CANT_MOVE_FOLDER; - nsIEnumerator *infoList=nsnull; - nsresult rv = m_hostinfo->GetSubFolders(&infoList); - - if (NS_SUCCEEDED(rv) && groupToMove && groupToMoveBefore && infoList) - { - nsIMsgFolder *folderToMoveBefore = getFolderFor(groupToMoveBefore); - if (m_groups->RemoveElement(groupToMove)) - { - // Not necessary to remove from infoList here because the folderPane does that (urk) - - // Unsubscribed groups are in the lists, but not in the view - nsIMsgFolder *group = nsnull; - PRInt32 idxInView, idxInData; - PRInt32 idxInHostInfo = 0; - infoList->First(); - PRBool foundIdxInHostInfo = PR_FALSE; - - PRUint32 cnt; - rv = m_groups->Count(&cnt); - if (NS_FAILED(rv)) return rv; - for (idxInData = 0, idxInView = -1; idxInData < (PRInt32)cnt; idxInData++) - { - group = (nsIMsgFolder*)m_groups->ElementAt(idxInData); - - nsIMsgFolder *groupInHostInfo; - (void)infoList->CurrentItem((nsISupports**)&groupInHostInfo); -#if 0 - nsISupports *hostInfoSupports; - (void)infoList->CurrentItem(&hostInfoSupports); - - nsIMsgFolder *groupInHostInfo=nsnull; - rv = hostInfoSupports->QueryInterface(NS_GET_IID(nsISupports), - (void **)&groupInHostInfo); -#endif -#ifdef HAVE_PANE - if (group->CanBeInFolderPane()) - idxInView++; -#endif - /* XXX - pointer comparisons are bad in COM! */ - if (group == folderToMoveBefore) - break; - if (groupInHostInfo == folderToMoveBefore) - foundIdxInHostInfo = PR_TRUE; - else if (!foundIdxInHostInfo) { - idxInHostInfo++; - infoList->Next(); - } - NS_RELEASE(groupInHostInfo); -#if 0 - NS_RELEASE(hostInfoSupports); -#endif - } - - if (idxInView != -1) - { - m_groups->InsertElementAt(groupToMove, idxInData); // the index has to be the same, right? - nsISupports* groupSupports; - groupToMove->QueryInterface(NS_GET_IID(nsISupports), - (void **)&groupSupports); -//XXX infoList->InsertElementAt(groupSupports, idxInHostInfo); - NS_RELEASE(groupSupports); - - MarkDirty (); // Make sure the newsrc gets written out in the new order - *newIdx = idxInView; // Tell the folder pane where the new item belongs - - err = 0; - NS_RELEASE(groupSupports); - } - } - } - return err; -} - - -PRInt32 -nsNNTPHost::DeleteFiles () -{ -#ifdef UNREADY_CODE - // hostinfo.dat - NS_ASSERTION(m_hostinfofilename, "null ptr"); - if (m_hostinfofilename) - XP_FileRemove (m_hostinfofilename, xpXoverCache); - - // newsrc file - const char *newsrc = GetNewsrcFileName(); - NS_ASSERTION(newsrc,"null ptr"); - if (newsrc) - XP_FileRemove (newsrc, xpNewsRC); - - // Delete directory - const char *dbdirname = GetDBDirName(); - NS_ASSERTION(dbdirname, "null ptr"); - if (dbdirname) - return XP_RemoveDirectory (dbdirname, xpXoverCache); -#endif - return 0; -} - -nsresult -nsNNTPHost::GetNewsgroupList(const char* name, nsINNTPNewsgroupList **_retval) -{ - nsresult result = NS_ERROR_NOT_INITIALIZED; - - if (name == nsnull) { - return NS_ERROR_NULL_POINTER; - } -#ifdef DEBUG_NEWS - printf("GetNewsgroupList(%s)\n",name); -#endif - - if (!m_newsgrouplists) return result; - PRUint32 cnt; - nsresult rv = m_newsgrouplists->Count(&cnt); - if (NS_FAILED(rv)) return rv; - PRInt32 n = cnt; - for (PRInt32 i=0 ; iElementAt(i); - rv = list->GetGroupName(&newsgroupname); - -#ifdef DEBUG_NEWS - printf("%d = %s\n",i,newsgroupname?newsgroupname:"null"); -#endif - - if (NS_SUCCEEDED(rv) && newsgroupname && PL_strcmp(name,newsgroupname) == 0) { - *_retval = list; - result = NS_OK; - } - } - return result; -} - -/* given a message id like asl93490@ahost.com, convert - * it to a newsgroup and a message number within that group - * (stolen from msgglue.cpp - MSG_NewsGroupAndNumberOfID) - */ -nsresult -nsNNTPHost::GetNewsgroupAndNumberOfID(const char *message_id, - nsINNTPNewsgroup **group, - PRUint32 *messageNumber) -{ -#ifdef HAVE_DBVIEW - MessageDBView *view = pane->GetMsgView(); - if (!view || !view->GetDB()) - return NS_ERROR_NOT_INITIALIZED; - nsMsgKey = view->GetDB()->GetMessageKeyForID(message_id); - *messageNumber = (nsMsgKey == nsMsgKey_None) ? 0 : nsMsgKey; -#endif - - /* Why are we always choosing the current pane's folder? */ -#ifdef HAVE_PANE - MSG_FolderInfo *folderInfo = pane->GetFolder(); - if (folderInfo != nsnull && folderInfo->IsNews()) - { - MSG_FolderInfoNews *newsFolderInfo = - (MSG_FolderInfoNews *) folderInfo; - *name = newsFolderInfo->GetNewsgroupName(); - } -#endif - return NS_OK; -} - -/* this function originally lived in a pane - */ -nsresult -nsNNTPHost::AddNewNewsgroup(const char *name, - PRInt32 first, - PRInt32 last, - const char *flags, - PRBool xactiveFlags) { - - nsMsgGroupRecord *groupRecord = nsnull; - -#ifdef DEBUG_NEWS - printf("nsNNTPHost::AddNewNewsgroup(%s,...)\n",name); -#endif - - PRInt32 status = NoticeNewGroup(name, &groupRecord); - if (status < 0) return status; - - /* this used to be for the pane */ - /* if (status > 0) m_numNewGroups++; */ - - PRBool bIsCategoryContainer = PR_FALSE; - PRBool bIsVirtual = PR_FALSE; - - while (flags && *flags) - { - char flag = toupper(*flags); - flags++; - switch (flag) - { - case 'C': - bIsCategoryContainer = PR_TRUE; - break; - case 'P': // profile - case 'V': - bIsVirtual = PR_TRUE; - break; - default: - break; - } - } - if (xactiveFlags) - { -#ifdef CATEGORIES_SUPPORTED - SetIsCategoryContainer(name, bIsCategoryContainer, groupRecord); -#endif /* CATEGORIES_SUPPORTED */ - SetIsVirtualGroup(name, bIsVirtual, groupRecord); - } - -#ifdef CATEGORIES_SUPPORTED - nsresult rv; - - if (status > 0) { - // If this really is a new newsgroup, then if it's a category of a - // subscribed newsgroup, then automatically subscribe to it. - char* containerName = GetCategoryContainer(name, groupRecord); - if (containerName) { - nsINNTPNewsgroup* categoryInfo; - rv = FindGroup(containerName, &categoryInfo); - - if (NS_SUCCEEDED(rv)) { - PRBool isSubscribed; - categoryInfo->GetSubscribed(&isSubscribed); - if (isSubscribed) { - // this autosubscribes categories of subscribed newsgroups. - nsINNTPNewsgroup *newsgroup; - rv = AddGroup(name, groupRecord, &newsgroup); - if (NS_SUCCEEDED(rv)) NS_RELEASE(newsgroup); - - } - NS_RELEASE(categoryInfo); - } - delete [] containerName; - } - } -#endif /* CATEGORIES_SUPPORTED */ - - if (status <=0) return NS_ERROR_UNEXPECTED; - - return NS_OK; -} - -nsresult -nsNNTPHost::DisplaySubscribedGroup(nsINNTPNewsgroup *newsgroup, - PRInt32 first_message, - PRInt32 last_message, - PRInt32 total_messages, - PRBool visit_now) -{ - nsresult rv = NS_OK; - - SetGroupSucceeded(PR_TRUE); - if (!newsgroup && visit_now) // let's try autosubscribe... - { -#if SETH_HACK - rv = AddGroup(group, nsnull, &newsgroup); -#else - NS_ASSERTION(0, "hack required."); -#endif - } - - if (!newsgroup) { - return NS_ERROR_FAILURE; - } - else { - PRBool subscribed; - rv = newsgroup->GetSubscribed(&subscribed); - if (NS_FAILED(rv)) return rv; - if (!subscribed) { - rv = newsgroup->SetSubscribed(PR_TRUE); - if (NS_FAILED(rv)) return rv; - } - } - - nsCOMPtr newsgroupList; - - rv = nsComponentManager::CreateInstance(kNNTPNewsgroupListCID, nsnull, NS_GET_IID(nsINNTPNewsgroupList), getter_AddRefs(newsgroupList)); - if (NS_FAILED(rv)) return rv; - - char *name = nsnull; - rv = newsgroup->GetName(&name); - if (NS_FAILED(rv)) return rv; - - rv = newsgroupList->Initialize(this, m_runningURL, newsgroup, m_username, m_hostname, name); - PR_FREEIF(name); - if (NS_FAILED(rv)) return rv; - - if (!m_newsgrouplists) { - rv = NS_NewISupportsArray(&m_newsgrouplists); - if (NS_FAILED(rv) || !m_newsgrouplists) { - return NS_ERROR_OUT_OF_MEMORY; - } - } - - //add newsgroupList to host's list of newsgroups - if (m_newsgrouplists) - m_newsgrouplists->AppendElement(newsgroupList); - - - rv = newsgroup->UpdateSummaryFromNNTPInfo(first_message, last_message, - total_messages); - return rv; -} - - -#define MSG_IMPL_GETFOLDER(_type)\ -nsIMsgFolder * \ -nsNNTPHost::getFolderFor(_type * _class) {\ - nsIMsgFolder* folder;\ - nsresult rv = \ - _class->QueryInterface(NS_GET_IID(nsIMsgFolder), (void **)&folder);\ - if (NS_SUCCEEDED(rv)) return folder;\ - else return nsnull;\ -}\ - -MSG_IMPL_GETFOLDER(nsINNTPNewsgroup) -MSG_IMPL_GETFOLDER(nsINNTPCategoryContainer) - - - - - diff --git a/mozilla/mailnews/news/src/nsNNTPHost.h b/mozilla/mailnews/news/src/nsNNTPHost.h deleted file mode 100644 index 8cb4e1b9cda..00000000000 --- a/mozilla/mailnews/news/src/nsNNTPHost.h +++ /dev/null @@ -1,425 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#ifndef __msg_NewsHost__ -#define __msg_NewsHost__ 1 - -#include "nsINNTPHost.h" - -#include "msgCore.h" // precompiled header... - -#include "nsMsgFolderFlags.h" - -#include "nntpCore.h" -#include "nsINNTPHost.h" -#include "nsINNTPCategory.h" - -#include "nsINNTPCategoryContainer.h" -#include "nsNNTPCategoryContainer.h" - -#include "nsNNTPHost.h" -#include "nsMsgKeySet.h" - -#include "nsMsgGroupRecord.h" - -#include "nsINNTPNewsgroup.h" -#include "nsNNTPNewsgroup.h" - -#include "nsINNTPNewsgroupList.h" -#include "nsNNTPNewsgroupList.h" - -#include "nsIMsgFolder.h" -#include "nsISupportsArray.h" -#include "nsIEnumerator.h" - -#include "nsFileStream.h" - -#include "nsNewsUtils.h" - -#include "prprf.h" -#include "prmem.h" -#include "plstr.h" -#include "plhash.h" -#include "prio.h" - -#include "nsCOMPtr.h" -#include "nsINntpUrl.h" - -/* temporary hacks to test if this compiles */ -typedef void MSG_GroupName; - -class nsNNTPHost : public nsINNTPHost { -public: - nsNNTPHost(); - virtual ~nsNNTPHost(); - - NS_DECL_ISUPPORTS - // nsINNTPHost - NS_IMETHOD Initialize(nsINntpUrl *runningURL, const char *username, const char *hostname); - - NS_IMPL_CLASS_GETSET(SupportsExtensions, PRBool, - m_supportsExtensions); - - NS_IMETHOD AddExtension (const char *ext); - NS_IMETHOD QueryExtension (const char *ext, PRBool *_retval); - - NS_IMPL_CLASS_GETSET(PostingAllowed, PRBool, m_postingAllowed); - - NS_IMPL_CLASS_GETTER(GetPushAuth, PRBool, m_pushAuth); - NS_IMETHOD SetPushAuth(PRBool value); - - NS_IMPL_CLASS_GETSET(LastUpdatedTime, PRUint32, m_lastGroupUpdate); - - NS_IMETHOD GetNewsgroupList(const char *name,nsINNTPNewsgroupList **_retval); - - NS_IMETHOD GetNewsgroupAndNumberOfID(const char *message_id, - nsINNTPNewsgroup **group, - PRUint32 *messageNumber); - - /* get this from MSG_Master::FindNewsFolder */ - NS_IMETHOD FindNewsgroup(const char *name, PRBool create, - nsINNTPNewsgroup **_retval) { NS_ASSERTION(0, "unimplemented!"); return NS_OK;} - - NS_IMETHOD AddPropertyForGet (const char *property, const char *value); - NS_IMETHOD QueryPropertyForGet (const char *property, char **_retval); - - NS_IMETHOD AddSearchableGroup(const char *name); - // should these go into interfaces? - NS_IMETHOD QuerySearchableGroup (const char *group, PRBool *); - NS_IMETHOD QuerySearchableGroupCharsets(const char *group, char **); - - // Virtual groups - NS_IMETHOD AddVirtualGroup(const char *responseText) { return NS_OK;} - NS_IMETHOD SetIsVirtualGroup(const char *name, PRBool isVirtual); - NS_IMETHOD SetIsVirtualGroup(const char *name, PRBool isVirtual, - nsMsgGroupRecord *inGroupRecord); - NS_IMETHOD GetIsVirtualGroup(const char *name, PRBool *_retval); - - // custom/searchable headers - NS_IMETHOD AddSearchableHeader(const char *headerName); - NS_IMETHOD QuerySearchableHeader(const char *headerName, PRBool *_retval); - - // Write out the newsrc for this host right now. In general, either - // MarkDirty() or WriteIfDirty() should be called instead. - NS_IMETHOD WriteNewsrc(); - - // Write out the newsrc for this host right now, if anything has changed - // in it. - NS_IMETHOD WriteIfDirty(); - - // Note that something has changed, and we need to rewrite the newsrc file - // for this host at some point. - NS_IMETHOD MarkDirty(); - - /* the Setter implementation is a little more complex */ - NS_IMPL_CLASS_GETTER(GetNewsRCFilename, char *, m_filename); - NS_IMETHOD SetNewsRCFilename(const char *); - - - // helper for accessing the above accessors from within this class - // (this is what the pre-mozilla API looked like) - char *GetNewsrcFileName() { return m_filename; }; - - NS_IMETHOD FindGroup(const char* name, nsINNTPNewsgroup* *_retval); - NS_IMETHOD AddGroup(const char *name, - nsINNTPNewsgroup **_retval); - - NS_IMETHOD AddGroup(const char *name, - nsMsgGroupRecord *groupRecord, - nsINNTPNewsgroup **_retval); - - NS_IMETHOD RemoveGroupByName(const char *name); - NS_IMETHOD RemoveGroup(nsINNTPNewsgroup*); - - NS_IMETHOD AddNewNewsgroup(const char *name, - PRInt32 first, - PRInt32 last, - const char *flags, - PRBool xactiveFlags); - - /* Name of directory to store newsgroup - databases in. This needs to have - "/name" appended to it, and the - whole thing can be passed to the XP_File - stuff with a type of xpXoverCache. */ - NS_IMETHOD GetDbDirName(char * *aDbDirName) {NS_ASSERTION(0, "unimplemented"); return NS_OK;}; - /* helper for internal accesses - part of the Pre-Mozilla API) */ - const char *GetDBDirName(); - - /* Returns a list of newsgroups. The result - must be free'd using PR_Free(); the - individual strings must not be free'd. */ - NS_IMETHOD GetGroupList(char **_retval) { return NS_OK;} - - NS_IMETHOD DisplaySubscribedGroup(nsINNTPNewsgroup *newsgroup, - PRInt32 first_message, - PRInt32 last_message, - PRInt32 total_messages, - PRBool visit_now); - // end of nsINNTPHost - -private: - // simplify the QueryInterface calls - static nsIMsgFolder *getFolderFor(nsINNTPNewsgroup *group); - static nsIMsgFolder *getFolderFor(nsINNTPCategoryContainer *catContainer); - - NS_METHOD CleanUp(); - virtual PRBool IsNews () { return PR_TRUE; } - virtual nsINNTPHost *GetNewsHost() { return this; } - - // - void addNew(MSG_GroupName* group); - void ClearNew(); - - // Get the nsIMsgFolder which represents this host; the children - // of this nsIMsgFolder are the groups in this host. - nsIMsgFolder* GetHostInfo() {return m_hostinfo;} - - // GetNumGroupsNeedingCounts() returns how many newsgroups we have - // that we don't have an accurate count of unread/total articles. - NS_IMETHOD GetNumGroupsNeedingCounts(PRInt32 *); - - // GetFirstGroupNeedingCounts() returns the name of the first newsgroup - // that does not have an accurate count of unread/total articles. The - // string must be free'd by the caller using PR_Free(). - NS_IMETHOD GetFirstGroupNeedingCounts(char **); - - - // GetFirstGroupNeedingExtraInfo() returns the name of the first newsgroup - // that does not have extra info (xactive flags and prettyname). The - // string must be free'd by the caller using PR_Free(). - NS_IMETHOD GetFirstGroupNeedingExtraInfo(char **); - - - void SetWantNewTotals(PRBool value); // Sets this bit on every newsgroup - // in this host. - - PRBool NeedsExtension (const char *ext); - - - - - // Returns the base part of the URL for this newshost, in the - // form "news://hostname:port" or "snews://hostname:port". - // Note that no trailing slash is appended, and that the - // ":port" part will be omitted if this host uses the default - // port. - const char* GetURLBase(); - - PRBool GetEverExpanded() {return m_everexpanded;} - void SetEverExpanded(PRBool value) {m_everexpanded = value;} - PRBool GetCheckedForNew() {return m_checkedForNew;} - void SetCheckedForNew(PRBool value) {m_checkedForNew = value;} - void SetGroupSucceeded(PRBool value) {m_groupSucceeded = value;} - // Completely obliterate this news host. Remove all traces of it from - // disk and memory. - PRInt32 RemoveHost(); - PRInt32 DeleteFiles(); - - // Returns the pretty name for the given group. The resulting string - // must be free'd using delete[]. - char* GetPrettyName(char* name); - NS_IMETHOD SetPrettyName(const char* name, const char* prettyname); - - PRTime GetAddTime(char* name); - - // Returns a unique integer associated with this newsgroup. This is - // mostly used by Win16 to generate a 8.3 filename. - PRInt32 GetUniqueID(char* name); - - PRBool IsCategory(char* name); - PRBool IsCategoryContainer(char* name); - PRInt32 SetIsCategoryContainer(const char* name, PRBool value, nsMsgGroupRecord *inGroupRecord = nsnull); - - NS_IMETHOD SetGroupNeedsExtraInfo(const char *name, PRBool value); - // Finds the container newsgroup for this category (or nsnull if this isn't - // a category). The resulting string must be free'd using delete[]. - char* GetCategoryContainer(const char* name, nsMsgGroupRecord *inGroupRecord = nsnull); - nsINNTPNewsgroup * GetCategoryContainerFolderInfo(const char *name); - - // Get/Set whether this is a real group (as opposed to a container of - // other groups, like "mcom".) - PRBool IsGroup(char* name); - PRInt32 SetIsGroup(char* name, PRBool value); - - - // Returns PR_TRUE if it's OK to post HTML in this group (either because the - // bit is on for this group, or one of this group's ancestor's has marked - // all of its descendents as being OK for HTML.) - PRBool IsHTMLOk(char* name); - - // Get/Set if it's OK to post HTML in just this group. - PRBool IsHTMLOKGroup(char* name); - PRInt32 SetIsHTMLOKGroup(char* name, PRBool value); - - // Get/Set if it's OK to post HTML in this group and all of its subgroups. - PRBool IsHTMLOKTree(char* name); - PRInt32 SetIsHTMLOKTree(char* name, PRBool value); - - // Create the given group (if not already present). Returns 0 if the - // group is already present, 1 if we had to create it, negative on error. - // The given group will have the "isgroup" bit set on it (in other words, - // it is not to be just a container of other groups, like "mcom" is.) - PRInt32 NoticeNewGroup(const char* name, nsMsgGroupRecord **outGroupRecord = nsnull); - - - // Makes sure that we have records in memory for all known descendants - // of the given newsgroup. - PRInt32 AssureAllDescendentsLoaded(nsMsgGroupRecord* group); - - - PRInt32 SaveHostInfo(); - - // Suck the entire hostinfo file into memory. If force is PR_TRUE, then throw - // away whatever we had in memory first. - PRInt32 Inhale(PRBool force = PR_FALSE); - - // If we inhale'd, then write thing out to the file and free up the - // memory. - PRInt32 Exhale(); - - // Inhale, but make believe the file is empty. In other words, set the - // inhaled bit, but empty out the memory. - PRInt32 EmptyInhale(); - - nsMsgGroupRecord* GetGroupTree() {return m_groupTree;} - PRTime GetFirstNewDate() {return m_firstnewdate;} - - NS_IMETHOD GroupNotFound(const char *name, PRBool opening); - - PRInt32 ReorderGroup (nsINNTPNewsgroup *groupToMove, nsINNTPNewsgroup *groupToMoveBefore, PRInt32 *newIdx); - -protected: - void OpenGroupFile(const PRIntn = PR_WRONLY); - - static void WriteTimer(void* closure); - PRInt32 CreateFileHeader(); - PRInt32 ReadInitialPart(); - nsMsgGroupRecord* FindGroupInBlock(nsMsgGroupRecord* parent, - char* name, - PRInt32* comp); - nsMsgGroupRecord* LoadSingleEntry(nsMsgGroupRecord* parent, - char* name, - PRInt32 min, PRInt32 max); - static PRInt32 InhaleLine(char* line, PRUint32 length, void* closure); - nsMsgGroupRecord* FindOrCreateGroup(const char* name, - PRInt32 * statusOfMakingGroup = nsnull); - - nsINNTPCategoryContainer *SwitchNewsToCategoryContainer(nsINNTPNewsgroup *newsInfo); - - nsINNTPNewsgroup * SwitchCategoryContainerToNews(nsINNTPCategoryContainer *catContainerInfo); - - char* m_hostname; - char* m_username; - - nsISupportsArray* m_groups; // List of nsINNTPNewsgroup* objects. - nsISupportsArray* m_newsgrouplists; // List of nsINNTPNewsgroupList* objects. - - nsIMsgFolder* m_hostinfo; // Object representing entire newshost in - // tree. - char* m_optionLines; - - - char* m_filename; /* The name of the newsrc file associated with - this host. This will be of the form: - - "" meaning .newsrc or .snewsrc - HOST meaning .newsrc-HOST - HOST:PORT meaning .newsrc-HOST:PORT - - Whether it begins with .newsrc or .snewsrc - depends on a special property slot - (we pass one of - the types xpNewsRC or xpSNewsRC to xp_file.) - - The reason this is not simply derived from - the host_name and port slots is that it's - not a 1:1 mapping; if the user has a file - called "newsrc", we will use that for the - default host (the "" name.) Likewise, - ".newsrc-H" and ".newsrc-H:119" are - ambiguous. - */ - - char* m_dbfilename; - PRBool m_dirty; - PRBool m_supportsExtensions; - void* m_writetimer; - char* m_urlbase; - PRBool m_everexpanded; // Whether the user ever opened up this - // newshost this session. - PRBool m_checkedForNew; // Whether we've checked for new newgroups - // in this newshost this session. - PRBool m_groupSucceeded; // Whether a group command has succeeded this - // session, protect against server bustage - // where it says no group exists. - - nsVoidArray m_supportedExtensions; - nsVoidArray m_searchableGroups; - nsVoidArray m_searchableHeaders; - // ### mwelch Added to determine what charsets can be used - // for each table. - PLHashTable * m_searchableGroupCharsets; - - nsVoidArray m_propertiesForGet; - nsVoidArray m_valuesForGet; - - PRBool m_postingAllowed; - PRBool m_pushAuth; // PR_TRUE if we should volunteer authentication without a - // challenge - - PRUint32 m_lastGroupUpdate; - PRTime m_firstnewdate; - - - nsMsgGroupRecord* m_groupTree; // Tree of groups we're remembering. - PRBool m_inhaled; // Whether we inhaled the entire list of - // groups, or just some. - PRInt32 m_groupTreeDirty; // Whether the group tree is dirty. If 0, then - // we don't need to write anything. If 1, then - // we can write things in place. If >1, then - // we need to rewrite the whole tree file. - char* m_hostinfofilename; // Filename of the hostinfo file. - - static nsNNTPHost* M_FileOwner; // In an effort to save file descriptors, - // only one newshost ever has its - // hostinfo file opened. This is the - // one. - - PRFileDesc * m_groupFile; // File handle to the hostinfo file. - char* m_groupFilePermissions; // Permissions used to create the above - // file handle. - - char* m_block; // A block of text read from the hostinfo file. - PRInt32 m_blockSize; // How many bytes allocated in m_block. - PRInt32 m_blockStart; // Where in the file we read the data that is - // currently sitting in m_block. - PRInt32 m_fileStart; // Where in the file the actual newsgroup data - // starts. - PRInt32 m_fileSize; // Total number of bytes in the hostinfo file. - PRInt32 m_uniqueId; // Unique number assigned to each newsgroup. - - nsINntpUrl *m_runningURL; - -}; - -#endif /* __msg_NewsHost__ */ diff --git a/mozilla/mailnews/news/src/nsNNTPNewsgroup.cpp b/mozilla/mailnews/news/src/nsNNTPNewsgroup.cpp deleted file mode 100644 index 0ef5e794337..00000000000 --- a/mozilla/mailnews/news/src/nsNNTPNewsgroup.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Seth Spitzer - * Pierre Phaneuf - */ - -#include "nscore.h" -#include "plstr.h" -#include "prmem.h" -#include - -#include "nsISupports.h" /* interface nsISupports */ - -#include "nsNNTPNewsgroup.h" - -#include "nsCOMPtr.h" - -nsNNTPNewsgroup::nsNNTPNewsgroup() -{ - NS_INIT_REFCNT(); - m_groupName = nsnull; - m_prettyName = nsnull; - m_needsExtraInfo = PR_FALSE; - m_category = PR_FALSE; -} - -nsNNTPNewsgroup::~nsNNTPNewsgroup() -{ -#ifdef DEBUG_NEWS - printf("destroying newsgroup: %s", m_groupName ? m_groupName : ""); -#endif - PR_FREEIF(m_groupName); - PR_FREEIF(m_prettyName); -} - -NS_IMPL_ISUPPORTS1(nsNNTPNewsgroup, nsINNTPNewsgroup) - -nsresult nsNNTPNewsgroup::GetName(char ** aName) -{ - if (aName) - { - *aName = PL_strdup(m_groupName); - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::SetName(const char *aName) -{ - if (aName) - { -#ifdef DEBUG_NEWS - printf("Setting newsgroup name to %s. \n", aName); -#endif - m_groupName = PL_strdup(aName); - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::GetPrettyName(char ** aName) -{ - if (aName) - { - *aName = PL_strdup(m_prettyName); - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::SetPrettyName(const char *aName) -{ - if (aName) - { -#ifdef DEBUG_NEWS - printf("Setting pretty newsgroup name to %s. \n", aName); -#endif - m_prettyName = PL_strdup(aName); - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::GetNeedsExtraInfo(PRBool *aNeedsExtraInfo) -{ - if (aNeedsExtraInfo) - { - *aNeedsExtraInfo = m_needsExtraInfo; - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::SetNeedsExtraInfo(PRBool aNeedsExtraInfo) -{ - if (aNeedsExtraInfo) - { -#ifdef DEBUG_NEWS - printf("Setting needs extra info for newsgroup %s to %s. \n", m_groupName, aNeedsExtraInfo ? "TRUE" : "FALSE" ); -#endif - m_needsExtraInfo = aNeedsExtraInfo; - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::IsOfflineArticle(PRInt32 num, PRBool *_retval) -{ -#ifdef DEBUG_NEWS - printf("Testing for offline article %d in %s. \n", num, m_groupName); -#endif - if (_retval) - *_retval = PR_FALSE; - return NS_OK; - -} - -nsresult nsNNTPNewsgroup::GetCategory(PRBool *aCategory) -{ - if (aCategory) - { - *aCategory = m_category; - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::SetCategory(PRBool aCategory) -{ - if (aCategory) - { -#ifdef DEBUG_NEWS - printf("Setting is category for newsgroup %s to %s. \n", m_groupName, aCategory ? "TRUE" : "FALSE" ); -#endif - m_category = aCategory; - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::GetSubscribed(PRBool *aSubscribed) -{ - if (aSubscribed) - { - *aSubscribed = m_isSubscribed; - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::SetSubscribed(PRBool aSubscribed) -{ - m_isSubscribed = aSubscribed; - - return NS_OK; -} - - nsresult nsNNTPNewsgroup::GetWantNewTotals(PRBool *aWantNewTotals) -{ - if (aWantNewTotals) - { - *aWantNewTotals = m_wantsNewTotals; - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::SetWantNewTotals(PRBool aWantNewTotals) -{ - if (aWantNewTotals) - { -#ifdef DEBUG_NEWS - printf("Setting wants new totals for newsgroup %s to %s. \n", m_groupName, aWantNewTotals ? "TRUE" : "FALSE" ); -#endif - m_wantsNewTotals = aWantNewTotals; - } - - return NS_OK; -} - - nsresult nsNNTPNewsgroup::GetNewsgroupList(nsINNTPNewsgroupList * *aNewsgroupList) -{ - if (aNewsgroupList) - { - *aNewsgroupList = m_newsgroupList; - NS_IF_ADDREF(*aNewsgroupList); - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::SetNewsgroupList(nsINNTPNewsgroupList * aNewsgroupList) -{ - if (aNewsgroupList) - { -#ifdef DEBUG_NEWS - printf("Setting newsgroup list for newsgroup %s. \n", m_groupName); -#endif - m_newsgroupList = aNewsgroupList; - NS_IF_ADDREF(aNewsgroupList); - } - - return NS_OK; -} - -nsresult nsNNTPNewsgroup::UpdateSummaryFromNNTPInfo(PRInt32 oldest, PRInt32 youngest, PRInt32 total_messages) -{ -#ifdef DEBUG_NEWS - printf("Updating summary with oldest= %d, youngest= %d, and total messages = %d. \n", oldest, youngest, total_messages); -#endif - return NS_OK; -} - -nsresult nsNNTPNewsgroup::Initialize(const char *name, - nsMsgKeySet *set, - PRBool subscribed) -{ -#ifdef DEBUG_NEWS - printf("nsNNTPNewsgroup::Intialize(name = %s, subscribed = %s)\n",name?name:"(null)", subscribed?"TRUE":"FALSE"); -#endif - nsresult rv = NS_OK; - - rv = SetSubscribed(subscribed); - if (NS_FAILED(rv)) return rv; - - if (name) { - rv = SetName((char *)name); - if (NS_FAILED(rv)) return rv; - } - - if (set) { - NS_ASSERTION(0, "not doing anything with set in nsNNTPNewsgroup::Initialize() yet..."); - } - - return rv; -} - diff --git a/mozilla/mailnews/news/src/nsNNTPNewsgroup.h b/mozilla/mailnews/news/src/nsNNTPNewsgroup.h deleted file mode 100644 index 5572f5b9db3..00000000000 --- a/mozilla/mailnews/news/src/nsNNTPNewsgroup.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#ifndef __nsNNTPNewsgroup_h -#define __nsNNTPNewsgroup_h - -#include "nsMsgKeySet.h" -#include "nsINNTPHost.h" -#include "nsINNTPNewsgroup.h" -#include "nsINNTPNewsgroupList.h" -#include "nsCOMPtr.h" - -class nsNNTPNewsgroup : public nsINNTPNewsgroup -{ -public: - nsNNTPNewsgroup(); - virtual ~nsNNTPNewsgroup(); - - NS_DECL_ISUPPORTS - NS_DECL_NSINNTPNEWSGROUP -protected: - char * m_groupName; - char * m_prettyName; - - PRBool m_isSubscribed; - PRBool m_wantsNewTotals; - PRBool m_needsExtraInfo; - PRBool m_category; - - nsCOMPtr m_newsgroupList; -}; - -#endif /* __nsNNTPNewsgroup_h */ diff --git a/mozilla/mailnews/news/src/nsNNTPNewsgroupList.cpp b/mozilla/mailnews/news/src/nsNNTPNewsgroupList.cpp index c50feb4cd17..bbc5e586694 100644 --- a/mozilla/mailnews/news/src/nsNNTPNewsgroupList.cpp +++ b/mozilla/mailnews/news/src/nsNNTPNewsgroupList.cpp @@ -51,12 +51,6 @@ #include "nsINNTPArticleList.h" #include "nsMsgKeySet.h" -#include "nsINNTPNewsgroup.h" -#include "nsNNTPNewsgroup.h" - -#include "nsINNTPHost.h" -#include "nsNNTPHost.h" - #include "nntpCore.h" #include "nsIStringBundle.h" @@ -91,11 +85,6 @@ extern PRInt32 net_NewsChunkSize; nsNNTPNewsgroupList::nsNNTPNewsgroupList() { NS_INIT_REFCNT(); - - m_username = nsnull; - m_hostname = nsnull; - m_uri = nsnull; - m_groupName = nsnull; } @@ -108,36 +97,17 @@ NS_IMPL_ISUPPORTS1(nsNNTPNewsgroupList, nsINNTPNewsgroupList) nsresult -nsNNTPNewsgroupList::Initialize(nsINNTPHost *host, nsINntpUrl *runningURL, nsINNTPNewsgroup *newsgroup, const char *username, const char *hostname, const char *groupname) +nsNNTPNewsgroupList::Initialize(nsINntpUrl *runningURL, nsIMsgNewsFolder *newsFolder) { - m_newsDB = nsnull; - - if (groupname) { - m_groupName = PL_strdup(groupname); - } - if (hostname) { - m_hostname = PL_strdup(hostname); - } - - if (username) { - m_username = PL_strdup(username); - m_uri = PR_smprintf("%s/%s@%s/%s",kNewsRootURI,username,hostname,groupname); - } - else { - m_uri = PR_smprintf("%s/%s/%s",kNewsRootURI,hostname,groupname); - } - - m_lastProcessedNumber = 0; + m_newsDB = nsnull; + m_lastProcessedNumber = 0; m_lastMsgNumber = 0; m_set = nsnull; m_finishingXover = PR_FALSE; memset(&m_knownArts, 0, sizeof(m_knownArts)); - m_knownArts.group_name = m_groupName; - m_host = host; - m_newsgroup = newsgroup; - m_knownArts.host = m_host; + m_newsFolder = newsFolder; m_knownArts.set = nsMsgKeySet::Create(); m_getOldMessages = PR_FALSE; m_promptedAlready = PR_FALSE; @@ -150,22 +120,21 @@ nsNNTPNewsgroupList::Initialize(nsINNTPHost *host, nsINntpUrl *runningURL, nsINN } nsresult -nsNNTPNewsgroupList::CleanUp() { - PR_FREEIF(m_username); - PR_FREEIF(m_hostname); - PR_FREEIF(m_uri); - PR_FREEIF(m_groupName); - +nsNNTPNewsgroupList::CleanUp() +{ if (m_newsDB) { m_newsDB->Commit(nsMsgDBCommitType::kSessionCommit); m_newsDB->Close(PR_TRUE); - NS_RELEASE(m_newsDB); - } + m_newsDB = nsnull; + } if (m_knownArts.set) { delete m_knownArts.set; m_knownArts.set = nsnull; } + + m_newsFolder = nsnull; + m_runningURL = nsnull; return NS_OK; } @@ -176,42 +145,6 @@ void nsNNTPNewsgroupList::OnAnnouncerGoingAway (ChangeAnnouncer *instigator) } #endif -nsresult -nsNNTPNewsgroupList::GetDatabase(const char *uri, nsIMsgDatabase **db) -{ - if (*db == nsnull) { - nsFileSpec path; - nsresult rv = nsNewsURI2Path(kNewsRootURI, uri, path); - if (NS_FAILED(rv)) return rv; - - nsresult newsDBOpen = NS_OK; - nsCOMPtr newsDBFactory; - - rv = nsComponentManager::CreateInstance(kCNewsDB, nsnull, NS_GET_IID(nsIMsgDatabase), getter_AddRefs(newsDBFactory)); - if (NS_SUCCEEDED(rv) && newsDBFactory) { - nsCOMPtr dbFileSpec; - NS_NewFileSpecWithSpec(path, getter_AddRefs(dbFileSpec)); - newsDBOpen = newsDBFactory->Open(dbFileSpec, PR_TRUE, PR_FALSE, (nsIMsgDatabase **) db); -#ifdef DEBUG_NEWS - if (NS_SUCCEEDED(newsDBOpen)) { - printf ("newsDBFactory->Open() succeeded\n"); - } - else { - printf ("newsDBFactory->Open() failed\n"); - } -#endif /* DEBUG_NEWS */ - return rv; - } -#ifdef DEBUG_NEWS - else { - printf("nsComponentManager::CreateInstance(kCNewsDB,...) failed\n"); - } -#endif - } - - return NS_OK; -} - static nsresult openWindow(nsIMsgWindow *aMsgWindow, const char *chromeURL, nsINewsDownloadDialogArgs *param) { @@ -264,8 +197,6 @@ openWindow(nsIMsgWindow *aMsgWindow, const char *chromeURL, nsINewsDownloadDialo nsresult nsNNTPNewsgroupList::GetRangeOfArtsToDownload(nsIMsgWindow * aMsgWindow, - /*nsINNTPHost* host, - const char* group_name,*/ PRInt32 first_possible, PRInt32 last_possible, PRInt32 maxextra, @@ -273,7 +204,7 @@ nsNNTPNewsgroupList::GetRangeOfArtsToDownload(nsIMsgWindow * aMsgWindow, PRInt32* last, PRInt32 *status) { - PRBool emptyGroup_p = PR_FALSE; + nsresult rv = NS_OK; NS_ASSERTION(first && last, "no first or no last"); if (!first || !last) return NS_MSG_FAILURE; @@ -281,126 +212,87 @@ nsNNTPNewsgroupList::GetRangeOfArtsToDownload(nsIMsgWindow * aMsgWindow, *first = 0; *last = 0; + nsCOMPtr folder = do_QueryInterface(m_newsFolder, &rv); + NS_ENSURE_SUCCESS(rv,rv); + if (!m_newsDB) { - nsresult err; - if ((err = GetDatabase(GetURI(), &m_newsDB)) != NS_OK) { - return err; - } - else { - nsresult rv = NS_OK; - - nsCOMPtr db(do_QueryInterface(m_newsDB, &rv)); - if (NS_FAILED(rv)) return rv; - - rv = db->GetReadSet(&m_set); - if (NS_FAILED(rv) || !m_set) { - return rv; - } - - m_set->SetLastMember(last_possible); // make sure highwater mark is valid. - nsCOMPtr newsGroupInfo; - rv = m_newsDB->GetDBFolderInfo(getter_AddRefs(newsGroupInfo)); - if (NS_SUCCEEDED(rv) && newsGroupInfo) - { - nsAutoString knownArtsString; - nsMsgKey mark; - newsGroupInfo->GetKnownArtsSet(&knownArtsString); - - rv = newsGroupInfo->GetHighWater(&mark); - if (NS_FAILED(rv)) { - return rv; - } - if (last_possible < ((PRInt32)mark)) - newsGroupInfo->SetHighWater(last_possible, PR_TRUE); - if (m_knownArts.set) { - delete m_knownArts.set; - } - nsCAutoString knownartstringC; - knownartstringC.AssignWithConversion(knownArtsString); - m_knownArts.set = nsMsgKeySet::Create(knownartstringC); - } - else - { - if (m_knownArts.set) { - delete m_knownArts.set; - } - m_knownArts.set = nsMsgKeySet::Create(); - nsMsgKey low, high; - rv = m_newsDB->GetLowWaterArticleNum(&low); - if (NS_FAILED(rv)) return rv; - rv = m_newsDB->GetHighWaterArticleNum(&high); - if (NS_FAILED(rv)) return rv; - - m_knownArts.set->AddRange(low,high); - } -#ifdef HAVE_PANES - m_pane->StartingUpdate(MSG_NotifyNone, 0, 0); - m_newsDB->ExpireUpTo(first_possible, m_pane->GetContext()); - m_pane->EndingUpdate(MSG_NotifyNone, 0, 0); -#endif /* HAVE_PANES */ - if (m_knownArts.set->IsMember(last_possible)) { - nsXPIDLString statusString; - nsCOMPtr bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr bundle; - rv = bundleService->CreateBundle(NEWS_MSGS_URL, nsnull, getter_AddRefs(bundle)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = bundle->GetStringFromName(NS_LITERAL_STRING("noNewMessages"), getter_Copies(statusString)); - NS_ENSURE_SUCCESS(rv, rv); - SetProgressStatus(statusString); - } - } + rv = folder->GetMsgDatabase(nsnull /* msgWindow */, getter_AddRefs(m_newsDB)); } + + nsCOMPtr db(do_QueryInterface(m_newsDB, &rv)); + NS_ENSURE_SUCCESS(rv,rv); + + rv = db->GetReadSet(&m_set); + if (NS_FAILED(rv) || !m_set) { + return rv; + } + + m_set->SetLastMember(last_possible); // make sure highwater mark is valid. + + nsCOMPtr newsGroupInfo; + rv = m_newsDB->GetDBFolderInfo(getter_AddRefs(newsGroupInfo)); + if (NS_SUCCEEDED(rv) && newsGroupInfo) { + nsAutoString knownArtsString; + nsMsgKey mark; + newsGroupInfo->GetKnownArtsSet(&knownArtsString); + + rv = newsGroupInfo->GetHighWater(&mark); + NS_ENSURE_SUCCESS(rv,rv); + + if (last_possible < ((PRInt32)mark)) + newsGroupInfo->SetHighWater(last_possible, PR_TRUE); + if (m_knownArts.set) { + delete m_knownArts.set; + } + nsCAutoString knownartstringC; + knownartstringC.AssignWithConversion(knownArtsString); + m_knownArts.set = nsMsgKeySet::Create(knownartstringC); + } + else + { + if (m_knownArts.set) { + delete m_knownArts.set; + } + m_knownArts.set = nsMsgKeySet::Create(); + nsMsgKey low, high; + rv = m_newsDB->GetLowWaterArticleNum(&low); + NS_ENSURE_SUCCESS(rv,rv); + rv = m_newsDB->GetHighWaterArticleNum(&high); + NS_ENSURE_SUCCESS(rv,rv); + + m_knownArts.set->AddRange(low,high); + } + + if (m_knownArts.set->IsMember(last_possible)) { + nsXPIDLString statusString; + nsCOMPtr bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr bundle; + rv = bundleService->CreateBundle(NEWS_MSGS_URL, nsnull, getter_AddRefs(bundle)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = bundle->GetStringFromName(NS_LITERAL_STRING("noNewMessages"), getter_Copies(statusString)); + NS_ENSURE_SUCCESS(rv, rv); + SetProgressStatus(statusString); + } if (maxextra <= 0 || last_possible < first_possible || last_possible < 1) { - emptyGroup_p = PR_TRUE; - } - - // this is just a temporary hack. these used to be parameters - // to this function, but then we were mutually dependant between this - // class and nsNNTPHost - nsINNTPHost *host=m_knownArts.host; - const char* group_name = m_knownArts.group_name; - if (m_knownArts.host != host || - m_knownArts.group_name == NULL || - PL_strcmp(m_knownArts.group_name, group_name) != 0 || - !m_knownArts.set) - { - /* We're displaying some other group. Clear out that display, and set up - everything to return the proper first chunk. */ - NS_ASSERTION(0, "todo - need new way of doing"); - if (emptyGroup_p) { - if (status) *status=0; - return NS_OK; - } - } - else - { - if (emptyGroup_p) { - if (status) *status=0; - return NS_OK; - } + if (status) *status=0; + return NS_OK; } m_knownArts.first_possible = first_possible; m_knownArts.last_possible = last_possible; - nsresult rv = NS_OK; - - // get the incoming msg server - NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, NS_MSGACCOUNTMANAGER_CONTRACTID, &rv) - if (NS_FAILED(rv)) return rv; - nsCOMPtr server; - rv = accountManager->FindServer(m_username,m_hostname,"nntp", getter_AddRefs(server)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr server; + rv = folder->GetServer(getter_AddRefs(server)); + NS_ENSURE_SUCCESS(rv,rv); // QI to get the nntp incoming msg server - nsCOMPtr nntpServer; - rv = server->QueryInterface(NS_GET_IID(nsINntpIncomingServer), getter_AddRefs(nntpServer)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr nntpServer = do_QueryInterface(server, &rv); + NS_ENSURE_SUCCESS(rv,rv); /* Determine if we only want to get just new articles or more messages. If there are new articles at the end we haven't seen, we always want to get those first. @@ -441,7 +333,11 @@ nsNNTPNewsgroupList::GetRangeOfArtsToDownload(nsIMsgWindow * aMsgWindow, rv = args->SetArticleCount(*last - *first + 1); NS_ENSURE_SUCCESS(rv,rv); - rv = args->SetGroupName((const char *)m_groupName); + nsXPIDLCString groupName; + rv = m_newsFolder->GetAsciiName(getter_Copies(groupName)); + NS_ENSURE_SUCCESS(rv,rv); + + rv = args->SetGroupName((const char *)groupName); NS_ENSURE_SUCCESS(rv,rv); // get the server key @@ -503,24 +399,12 @@ nsresult nsNNTPNewsgroupList::AddToKnownArticles(PRInt32 first, PRInt32 last) { int status; - // another temporary hack - nsINNTPHost *host = m_knownArts.host; - const char* group_name = m_knownArts.group_name; - - if (m_knownArts.host != host || - m_knownArts.group_name == NULL || - PL_strcmp(m_knownArts.group_name, group_name) != 0 || - !m_knownArts.set) + + if (!m_knownArts.set) { - m_knownArts.host = host; - PR_FREEIF(m_knownArts.group_name); - m_knownArts.group_name = PL_strdup(group_name); - if (m_knownArts.set) { - delete m_knownArts.set; - } m_knownArts.set = nsMsgKeySet::Create(); - if (!m_knownArts.group_name || !m_knownArts.set) { + if (!m_knownArts.set) { return NS_ERROR_OUT_OF_MEMORY; } @@ -536,7 +420,7 @@ nsNNTPNewsgroupList::AddToKnownArticles(PRInt32 first, PRInt32 last) char *output; status = m_knownArts.set->Output(&output); if (output) { - nsString str; str.AssignWithConversion(output); + nsAutoString str; str.AssignWithConversion(output); newsGroupInfo->SetKnownArtsSet(&str); nsMemory::Free(output); } @@ -919,50 +803,18 @@ nsNNTPNewsgroupList::FinishXOVERLINE(int status, int *newstatus) SetProgressStatus(statusString); } -#ifdef HAVE_PANES - nsINNTPNewsgroup *newsFolder = - (m_pane) ? - savePane->GetMaster()->FindNewsFolder(m_host, m_groupName, PR_FALSE) : - 0; - FE_PaneChanged(m_pane, PR_FALSE, MSG_PaneNotifyFolderLoaded, (PRUint32)newsFolder); -#endif } if (newstatus) *newstatus=0; return NS_OK; // nsNNTPNewsgroupList object gets deleted by the master when a new one is created. } -// this used to be in the master: -// void MSG_Master::ClearListNewsGroupState(MSG_NewsHost* host, -// const char *newsGroupName) -// { -// MSG_FolderInfoNews *newsFolder = FindNewsFolder(host, newsGroupName); -// ListNewsGroupState *state = (newsFolder) ? newsFolder->GetListNewsGroupState -// if (state != NULL) -// { -// delete state; -// newsFolder->SetListNewsGroupState(NULL); -// } -// } - nsresult nsNNTPNewsgroupList::ClearXOVERState() { return NS_OK; } -nsresult -nsNNTPNewsgroupList::GetGroupName(char **_retval) -{ - if (_retval) { - *_retval = m_groupName; - return NS_OK; - } - else { - return NS_ERROR_NULL_POINTER; - } -} - void nsNNTPNewsgroupList::SetProgressBarPercent(PRInt32 percent) { diff --git a/mozilla/mailnews/news/src/nsNNTPNewsgroupList.h b/mozilla/mailnews/news/src/nsNNTPNewsgroupList.h index 8a99309c432..8f9c6eec0c7 100644 --- a/mozilla/mailnews/news/src/nsNNTPNewsgroupList.h +++ b/mozilla/mailnews/news/src/nsNNTPNewsgroupList.h @@ -29,9 +29,8 @@ #ifndef nsNNTPNewsgroupListState_h___ #define nsNNTPNewsgroupListState_h___ -#include "nsINNTPHost.h" #include "nsINNTPNewsgroupList.h" -#include "nsINNTPNewsgroup.h" +#include "nsIMsgNewsFolder.h" #include "nsIMsgDatabase.h" #include "nsMsgKeySet.h" #include "nsINntpUrl.h" @@ -41,8 +40,6 @@ articles we've already seen in the current newsgroup. */ typedef struct MSG_NewsKnown { - nsINNTPHost* host; - char* group_name; nsMsgKeySet* set; /* Set of articles we've already gotten from the newsserver (if it's marked "read", then we've already gotten it). @@ -77,9 +74,7 @@ private: NS_METHOD CleanUp(); PRBool m_finishingXover; - nsINNTPHost* GetHost() {return m_host;} - const char * GetURI() {return m_uri;} - + #ifdef HAVE_CHANGELISTENER virtual void OnAnnouncerGoingAway (ChangeAnnouncer *instigator); #endif @@ -89,17 +84,13 @@ private: void SetProgressStatus(const PRUnichar *message); protected: - nsIMsgDatabase *m_newsDB; PRBool m_getOldMessages; PRBool m_promptedAlready; PRBool m_downloadAll; PRInt32 m_maxArticles; - char *m_groupName; - nsINNTPHost *m_host; - nsINNTPNewsgroup *m_newsgroup; - char *m_username; - char *m_hostname; - char *m_uri; + + nsCOMPtr m_newsFolder; + nsCOMPtr m_newsDB; nsMsgKey m_lastProcessedNumber; nsMsgKey m_firstMsgNumber; @@ -109,7 +100,7 @@ protected: struct MSG_NewsKnown m_knownArts; nsMsgKeySet *m_set; - nsINntpUrl *m_runningURL; + nsINntpUrl *m_runningURL; }; #endif /* nsNNTPNewsgroupListState_h___ */ diff --git a/mozilla/mailnews/news/src/nsNNTPProtocol.cpp b/mozilla/mailnews/news/src/nsNNTPProtocol.cpp index 5ae7c151f98..61c69204b0f 100644 --- a/mozilla/mailnews/news/src/nsNNTPProtocol.cpp +++ b/mozilla/mailnews/news/src/nsNNTPProtocol.cpp @@ -83,6 +83,7 @@ #include "nsIMsgWindow.h" #include "nsIPrompt.h" +#include "nsINntpService.h" #include "nntpCore.h" #undef GetPort // XXX Windows! @@ -152,7 +153,6 @@ char * NET_SACat (char **destination, const char *source); static NS_DEFINE_CID(kCHeaderParserCID, NS_MSGHEADERPARSER_CID); static NS_DEFINE_CID(kNNTPArticleListCID, NS_NNTPARTICLELIST_CID); -static NS_DEFINE_CID(kNNTPHostCID, NS_NNTPHOST_CID); static NS_DEFINE_CID(kCMsgMailSessionCID, NS_MSGMAILSESSION_CID); static NS_DEFINE_CID(kCMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID); static NS_DEFINE_CID(kPrefServiceCID,NS_PREF_CID); @@ -457,6 +457,7 @@ nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow) m_cancelID = nsnull; m_messageID = nsnull; + m_key = nsMsgKey_None; m_commandSpecificData = nsnull; m_searchData = nsnull; @@ -573,10 +574,6 @@ NS_IMETHODIMP nsNNTPProtocol::Initialize(nsIURI * aURL, nsIMsgWindow *aMsgWindow } // 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 (msgIsInLocalCache) return NS_OK; // probably don't need to do anything else - definitely don't want @@ -626,6 +623,7 @@ NS_IMETHODIMP nsNNTPProtocol::Initialize(nsIURI * aURL, nsIMsgWindow *aMsgWindow PR_FREEIF(m_messageID); m_messageID = nsnull; + m_key = nsMsgKey_None; m_articleNumber = 0; m_originalContentLength = 0; @@ -636,13 +634,6 @@ NS_IMETHODIMP nsNNTPProtocol::Initialize(nsIURI * aURL, nsIMsgWindow *aMsgWindow return NS_OK; } -nsresult -nsNNTPProtocol::InitializeNewsFolderFromUri(const char *uri) -{ - PR_LOG(NNTP,PR_LOG_ALWAYS,("InitializeNewsFolderFromUri(%s)",uri)); - return nsGetNewsGroupFromUri(uri, getter_AddRefs(m_newsFolder)); -} - /* void IsBusy (out boolean aIsConnectionBusy); */ NS_IMETHODIMP nsNNTPProtocol::IsBusy(PRBool *aIsConnectionBusy) { @@ -771,7 +762,7 @@ NS_IMETHODIMP nsNNTPProtocol::AsyncRead(nsIStreamListener *listener, nsISupports nsCOMPtr mailnewsUrl = do_QueryInterface(m_runningURL, &rv); if (NS_FAILED(rv)) return rv; - SetNewsFolder(); // make sure m_newsFolder is set. + SetNewsFolderAndMsgKey(); // make sure m_newsFolder is set. m_channelContext = ctxt; m_channelListener = listener; m_runningURL->GetNewsAction(&m_newsAction); @@ -791,10 +782,8 @@ NS_IMETHODIMP nsNNTPProtocol::AsyncRead(nsIStreamListener *listener, nsISupports if (folder && NS_SUCCEEDED(rv)) { // we want to create a file channel and read the msg from there. - nsMsgKey key = nsMsgKey_None; - rv = m_runningURL->GetMessageKey(&key); nsCOMPtr fileChannel; - rv = folder->GetOfflineFileChannel(key, getter_AddRefs(fileChannel)); + rv = folder->GetOfflineFileChannel(m_key, getter_AddRefs(fileChannel)); // get the file channel from the folder, somehow (through the message or // folder sink?) We also need to set the transfer offset to the message offset if (fileChannel && NS_SUCCEEDED(rv)) @@ -895,7 +884,9 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) m_runningURL->GetNewsAction(&m_newsAction); nsCOMPtr mailnewsUrl = do_QueryInterface(m_runningURL); - SetNewsFolder(); // make sure m_newsFolder is set. + if (m_newsAction != nsINntpUrl::ActionPostArticle) { + SetNewsFolderAndMsgKey(); // set m_newsFolder and m_key, if we can + } m_articleNumber = -1; rv = aURL->GetHost(getter_Copies(m_hostName)); @@ -907,10 +898,6 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) // 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)); @@ -918,45 +905,16 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) PR_FREEIF(m_messageID); m_messageID = nsnull; + rv = ParseURL(aURL,&bVal, getter_Copies(group), &m_messageID, &commandSpecificData); NS_ASSERTION(NS_SUCCEEDED(rv),"failed to parse news url"); //if (NS_FAILED(rv)) return rv; - // if we don't have a news host already, go get one... - if (!m_newsHost) - { - m_newsHost = do_CreateInstance(kNNTPHostCID, &rv); - if (NS_FAILED(rv) || (!m_newsHost)) goto FAIL; + + if (!m_newsFolder) goto FAIL; - // m_newsHost holds m_runningURL (make this a weak reference) - // m_runningURL holds m_newsHost - // need to make sure there is no cycle. - - // retrieve the AccountManager - NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, NS_MSGACCOUNTMANAGER_CONTRACTID, &rv); - if (NS_FAILED(rv)) goto FAIL; - - // find the incoming server - nsCOMPtr server; - rv = accountManager->FindServer(m_userName, - m_hostName, - "nntp", - getter_AddRefs(server)); - if (NS_FAILED(rv) || !server) goto FAIL; - - m_nntpServer = do_QueryInterface(server, &rv); - if (NS_FAILED(rv) || !m_nntpServer) goto FAIL; - - m_newsHost->Initialize(m_runningURL, m_userName, m_hostName); - - // save it on our url for future use.... - m_runningURL->SetNntpHost(m_newsHost); - - if (NS_FAILED(rv)) goto FAIL; - } - - if (NS_FAILED(rv)) - goto FAIL; + rv = m_newsFolder->GetNntpServer(getter_AddRefs(m_nntpServer)); + if (NS_FAILED(rv) || !m_nntpServer) goto FAIL; if (m_messageID && commandSpecificData && !PL_strcmp (commandSpecificData, "?cancel")) cancel = PR_TRUE; @@ -996,11 +954,16 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) NET_SACopy(&m_path, ""); } else - if (m_messageID) + if (m_messageID || (m_key != nsMsgKey_None)) { - /* news:MESSAGE_ID - news:/GROUP/MESSAGE_ID (useless) + /* + news_message://HOST/GROUP#key news://HOST/MESSAGE_ID + + not sure about these: + + news:MESSAGE_ID + news:/GROUP/MESSAGE_ID (useless) news://HOST/GROUP/MESSAGE_ID (useless) */ if (cancel) @@ -1079,8 +1042,8 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer) if (NS_FAILED(rv)) return rv; } } - - rv = InitializeNewsFolderFromUri((const char *)newsgroupURI); + + rv = nsGetNewsGroupFromUri((const char *)newsgroupURI, getter_AddRefs(m_newsFolder)); if (NS_FAILED(rv)) return rv; m_typeWanted = GROUP_WANTED; @@ -1517,10 +1480,7 @@ PRInt32 nsNNTPProtocol::LoginResponse() return MK_BAD_NNTP_CONNECTION; } - // ###mscott: I'm commenting this out right now since phil has a comment saying it is dead code... - // cd->control_con->posting_allowed = postingAllowed; /* ###phil dead code */ - - m_newsHost->SetPostingAllowed(postingAllowed); + m_nntpServer->SetPostingAllowed(postingAllowed); m_nextState = NNTP_SEND_MODE_READER; return(0); /* good */ } @@ -1546,7 +1506,7 @@ PRInt32 nsNNTPProtocol::SendModeReaderResponse() /* ignore the response code and continue */ PRBool pushAuth; - nsresult rv = m_newsHost->GetPushAuth(&pushAuth); + nsresult rv = m_nntpServer->GetPushAuth(&pushAuth); if (NS_SUCCEEDED(rv) && pushAuth) /* if the news host is set up to require volunteered (pushed) authentication, * do that before we do anything else @@ -1593,12 +1553,13 @@ PRInt32 nsNNTPProtocol::SendListExtensionsResponse(nsIInputStream * inputStream, if (!line) return status; /* no line yet */ - if ('.' != line[0]) - m_newsHost->AddExtension(line); + if ('.' != line[0]) { + m_nntpServer->AddExtension(line); + } else { /* tell libmsg that it's ok to ask this news host for extensions */ - m_newsHost->SetSupportsExtensions(PR_TRUE); + m_nntpServer->SetSupportsExtensions(PR_TRUE); /* all extensions received */ m_nextState = SEND_LIST_SEARCHES; ClearFlag(NNTP_PAUSE_FOR_READ); @@ -1610,7 +1571,7 @@ PRInt32 nsNNTPProtocol::SendListExtensionsResponse(nsIInputStream * inputStream, * tell libmsg not to ask for any more extensions and move on to * the real NNTP command we were trying to do. */ - m_newsHost->SetSupportsExtensions(PR_FALSE); + m_nntpServer->SetSupportsExtensions(PR_FALSE); m_nextState = SEND_FIRST_NNTP_COMMAND; } @@ -1623,7 +1584,7 @@ PRInt32 nsNNTPProtocol::SendListSearches() PRBool searchable=PR_FALSE; PRInt32 status = 0; - rv = m_newsHost->QueryExtension("SEARCH",&searchable); + rv = m_nntpServer->QueryExtension("SEARCH",&searchable); if (NS_SUCCEEDED(rv) && searchable) { nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); @@ -1666,7 +1627,7 @@ PRInt32 nsNNTPProtocol::SendListSearchesResponse(nsIInputStream * inputStream, P if ('.' != line[0]) { - m_newsHost->AddSearchableGroup(line); + m_nntpServer->AddSearchableGroup(line); } else { @@ -1712,7 +1673,7 @@ PRInt32 nsNNTPProtocol::SendListSearchHeadersResponse(nsIInputStream * inputStre return status; /* no line yet */ if ('.' != line[0]) - m_newsHost->AddSearchableHeader(line); + m_nntpServer->AddSearchableHeader(line); else { m_nextState = NNTP_GET_PROPERTIES; @@ -1729,7 +1690,7 @@ PRInt32 nsNNTPProtocol::GetProperties() PRBool setget=PR_FALSE; PRInt32 status = 0; - rv = m_newsHost->QueryExtension("SETGET",&setget); + rv = m_nntpServer->QueryExtension("SETGET",&setget); if (NS_SUCCEEDED(rv) && setget) { nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); @@ -1774,7 +1735,7 @@ PRInt32 nsNNTPProtocol::GetPropertiesResponse(nsIInputStream * inputStream, PRUi { char *propertyValue = space + 1; *space = '\0'; - m_newsHost->AddPropertyForGet(propertyName, propertyValue); + m_nntpServer->AddPropertyForGet(propertyName, propertyValue); } PR_Free(propertyName); } @@ -1796,7 +1757,7 @@ PRInt32 nsNNTPProtocol::SendListSubscriptions() #if 0 nsresult rv; PRBool searchable=PR_FALSE; - rv = m_newsHost->QueryExtension("LISTSUBSCR",&listsubscr); + rv = m_nntpServer->QueryExtension("LISTSUBSCR",&listsubscr); if (NS_SUCCEEDED(rv) && listsubscr) #else if (0) @@ -1865,17 +1826,21 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommand(nsIURI * url) if (m_typeWanted == ARTICLE_WANTED) { - nsresult rv1,rv2; + nsresult rv; - nsMsgKey key = nsMsgKey_None; - rv1 = m_runningURL->GetMessageKey(&key); - nsXPIDLCString newsgroupName; - rv2 = m_runningURL->GetNewsgroupName(getter_Copies(newsgroupName)); + if (m_newsFolder) { + rv = m_newsFolder->GetAsciiName(getter_Copies(newsgroupName)); + NS_ENSURE_SUCCESS(rv,rv); + } + else { + printf("no news folder!\n"); + rv = NS_ERROR_UNEXPECTED; + } - if (NS_SUCCEEDED(rv1) && NS_SUCCEEDED(rv2) && ((const char *)newsgroupName) && (key != nsMsgKey_None)) + if (NS_SUCCEEDED(rv) && ((const char *)newsgroupName) && (m_key != nsMsgKey_None)) { - m_articleNumber = key; + m_articleNumber = m_key; if (((const char *)m_currentGroup) && !PL_strcmp ((const char *)m_currentGroup, (const char *)newsgroupName)) m_nextState = NNTP_SEND_ARTICLE_NUMBER; @@ -1908,11 +1873,11 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommand(nsIURI * url) PRUint32 last_update; nsresult rv; - if (!m_newsHost) { - NNTP_LOG_NOTE("m_newsHost is null, panic!"); + if (!m_nntpServer) { + NNTP_LOG_NOTE("m_nntpServer is null, panic!"); return -1; } - rv = m_newsHost->GetLastUpdatedTime(&last_update); + rv = m_nntpServer->GetLastUpdatedTime(&last_update); char small_buf[64]; PRExplodedTime expandedTime; @@ -1945,11 +1910,11 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommand(nsIURI * url) ClearFlag(NNTP_USE_FANCY_NEWSGROUP); PRUint32 last_update; - if (!m_newsHost) { - NNTP_LOG_NOTE("m_newsHost is null, panic!"); + if (!m_nntpServer) { + NNTP_LOG_NOTE("m_nntpServer is null, panic!"); return -1; } - nsresult rv = m_newsHost->GetLastUpdatedTime(&last_update); + nsresult rv = m_nntpServer->GetLastUpdatedTime(&last_update); if (NS_SUCCEEDED(rv) && last_update!=0) { @@ -1968,7 +1933,7 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommand(nsIURI * url) #endif /* BUG_21013 */ #endif PRBool xactive=PR_FALSE; - rv = m_newsHost->QueryExtension("XACTIVE",&xactive); + rv = m_nntpServer->QueryExtension("XACTIVE",&xactive); if (NS_SUCCEEDED(rv) && xactive) { NET_SACopy(&command, "LIST XACTIVE"); @@ -1982,44 +1947,37 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommand(nsIURI * url) } else if(m_typeWanted == GROUP_WANTED) { - /* Don't use MKParse because the news: access URL doesn't follow traditional - * rules. For instance, if the article reference contains a '#', - * the rest of it is lost. - */ - char * slash; - char * group_name; - nsresult rv=NS_ERROR_NULL_POINTER; - - NET_SACopy(&command, "GROUP "); - if (!m_newsgroup) { - NNTP_LOG_NOTE("m_newsHost is null, panic!"); + nsXPIDLCString group_name; + nsresult rv = NS_ERROR_NULL_POINTER; + + NS_ASSERTION(m_newsFolder, "m_newsFolder is null, panic!"); + if (!m_newsFolder) { return -1; } - - rv = m_newsgroup->GetName(&group_name); - slash = PL_strchr(group_name, '/'); + + rv = m_newsFolder->GetAsciiName(getter_Copies(group_name)); + NS_ASSERTION(NS_SUCCEEDED(rv),"failed to get newsgroup name"); + if (NS_FAILED(rv)) { + return -1; + } m_firstArticle = 0; m_lastArticle = 0; - if (slash) - { - *slash = '\0'; - (void) PR_sscanf(slash+1, "%d-%d", &m_firstArticle, &m_lastArticle); - } + + NET_SACopy(&command, "GROUP "); - m_currentGroup = group_name; + m_currentGroup = (const char *)group_name; NET_SACat(&command, (const char *)m_currentGroup); - PR_FREEIF(group_name); } else if (m_typeWanted == SEARCH_WANTED) { nsresult rv; PRBool searchable=PR_FALSE; - if (!m_newsHost) { - NNTP_LOG_NOTE("m_newsHost is null, panic!"); + if (!m_nntpServer) { + NNTP_LOG_NOTE("m_nntpServer is null, panic!"); return -1; } - rv = m_newsHost->QueryExtension("SEARCH", &searchable); + rv = m_nntpServer->QueryExtension("SEARCH", &searchable); if (NS_SUCCEEDED(rv) && searchable) { /* use the SEARCH extension */ @@ -2042,11 +2000,12 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommand(nsIURI * url) /* for XPAT, we have to GROUP into the group before searching */ NET_SACopy(&command, "GROUP "); - if (!m_newsgroup) { - NNTP_LOG_NOTE("m_newsHost is null, panic!"); + if (!m_newsFolder) { + NNTP_LOG_NOTE("m_newsFolder is null, panic!"); return -1; } - rv = m_newsgroup->GetName(getter_Copies(group_name)); + rv = m_newsFolder->GetAsciiName(getter_Copies(group_name)); + if (NS_FAILED(rv)) return -1; NET_SACat (&command, group_name); m_nextState = NNTP_RESPONSE; m_nextStateAfterResponse = NNTP_XPAT_SEND; @@ -2056,7 +2015,7 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommand(nsIURI * url) { nsresult rv; PRBool listpretty=PR_FALSE; - rv = m_newsHost->QueryExtension("LISTPRETTY",&listpretty); + rv = m_nntpServer->QueryExtension("LISTPRETTY",&listpretty); if (NS_SUCCEEDED(rv) && listpretty) { m_nextState = NNTP_LIST_PRETTY_NAMES; @@ -2146,12 +2105,8 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommandResponse() if (m_responseCode == MK_NNTP_RESPONSE_GROUP_NO_GROUP && m_typeWanted == GROUP_WANTED) { NNTP_LOG_NOTE("group not found!"); -#ifdef UNREADY_CODE - MSG_GroupNotFound(cd->pane, cd->host, cd->control_con->current_group, PR_TRUE /* opening group */); -#else - m_newsHost->GroupNotFound((const char *)m_currentGroup, + m_nntpServer->GroupNotFound((const char *)m_currentGroup, PR_TRUE /* opening */); -#endif } /* if the server returned a 400 error then it is an expected @@ -2165,8 +2120,8 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommandResponse() nsresult rv = NS_OK; nsXPIDLCString group_name; - if (m_newsgroup) { - rv = m_newsgroup->GetName(getter_Copies(group_name)); + if (m_newsFolder) { + rv = m_newsFolder->GetAsciiName(getter_Copies(group_name)); } if (NS_SUCCEEDED(rv) && group_name) { @@ -2188,15 +2143,11 @@ PRInt32 nsNNTPProtocol::SendFirstNNTPCommandResponse() NS_ENSURE_SUCCESS(rv,rv); errorHtml.Append(newsErrorStr); - nsMsgKey key = nsMsgKey_None; - rv = m_runningURL->GetMessageKey(&key); - NS_ENSURE_SUCCESS(rv,rv); - char outputBuffer[OUTPUT_BUFFER_SIZE]; - NS_ASSERTION(m_messageID && (key != nsMsgKey_None), "unexpected"); - if (m_messageID && (key != nsMsgKey_None)) { - PR_snprintf(outputBuffer,OUTPUT_BUFFER_SIZE,"

<%.512s> (%lu)", m_messageID, key); + NS_ASSERTION(m_messageID && (m_key != nsMsgKey_None), "unexpected"); + if (m_messageID && (m_key != nsMsgKey_None)) { + PR_snprintf(outputBuffer,OUTPUT_BUFFER_SIZE,"

<%.512s> (%lu)", m_messageID, m_key); errorHtml.AppendWithConversion(outputBuffer); } @@ -2249,7 +2200,7 @@ PRInt32 nsNNTPProtocol::SendGroupForArticle() PRInt32 status = 0; nsXPIDLCString groupname; - rv = m_newsgroup->GetName(getter_Copies(groupname)); + rv = m_newsFolder->GetAsciiName(getter_Copies(groupname)); NS_ASSERTION(NS_SUCCEEDED(rv) && (const char *)groupname && nsCRT::strlen((const char *)groupname), "no group name"); char outputBuffer[OUTPUT_BUFFER_SIZE]; @@ -2278,7 +2229,7 @@ PRInt32 nsNNTPProtocol::SendGroupForArticleResponse() m_nextState = NNTP_SEND_ARTICLE_NUMBER; nsXPIDLCString groupname; - rv = m_newsgroup->GetName(getter_Copies(groupname)); + rv = m_newsFolder->GetAsciiName(getter_Copies(groupname)); NS_ASSERTION(NS_SUCCEEDED(rv) && (const char *)groupname && nsCRT::strlen((const char *)groupname), "no group name"); m_currentGroup = (const char *)groupname; @@ -2642,23 +2593,32 @@ void nsNNTPProtocol::ParseHeaderForCancel(char *buf) } nsresult -nsNNTPProtocol::SetNewsFolder() +nsNNTPProtocol::SetNewsFolderAndMsgKey() { nsresult rv; // xxx todo: I need to fix this so this is passed in when I create the nsNNTPProtocol - if (!m_newsFolder) { - nsXPIDLCString folderURI; - nsXPIDLCString newsgroupName; - rv = m_runningURL->GetNewsgroupName(getter_Copies(newsgroupName)); - if (NS_FAILED(rv)) return rv; + if (!m_newsFolder || (m_key == nsMsgKey_None)) { + nsXPIDLCString uri; + nsCOMPtr msgUrl = do_QueryInterface(m_runningURL, &rv); + NS_ENSURE_SUCCESS(rv,rv); - rv = CreateNewsFolderURI((const char *)m_userName,(const char *)m_hostName, (const char *)newsgroupName, getter_Copies(folderURI)); - if (NS_FAILED(rv)) return rv; + rv = msgUrl->GetUri(getter_Copies(uri)); + NS_ENSURE_SUCCESS(rv,rv); - rv = InitializeNewsFolderFromUri((const char *)folderURI); - if (NS_FAILED(rv)) return rv; +#ifdef DEBUG_seth + printf("SetNewsFolderAndMsgKey in nsNNTPProtocol with %s\n",(const char *)uri); +#endif + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); + + nsCOMPtr folder; + rv = nntpService->DecomposeNewsURI((const char *)uri, getter_AddRefs(folder), &m_key); + NS_ENSURE_SUCCESS(rv,rv); + + m_newsFolder = do_QueryInterface(folder, &rv); + NS_ENSURE_SUCCESS(rv,rv); } return NS_OK; } @@ -2697,7 +2657,7 @@ PRInt32 nsNNTPProtocol::BeginAuthorization() PRInt32 status = 0; nsXPIDLCString cachedUsername; - SetNewsFolder(); + SetNewsFolderAndMsgKey(); if (m_newsFolder) { rv = m_newsFolder->GetGroupUsername(getter_Copies(cachedUsername)); @@ -2777,7 +2737,7 @@ PRInt32 nsNNTPProtocol::AuthorizationResponse() /* If we're here because the host demanded authentication before we * even sent a single command, then jump back to the beginning of everything */ - rv = m_newsHost->GetPushAuth(&pushAuth); + rv = m_nntpServer->GetPushAuth(&pushAuth); if (!TestFlag(NNTP_READER_PERFORMED)) m_nextState = NNTP_SEND_MODE_READER; @@ -2806,7 +2766,8 @@ PRInt32 nsNNTPProtocol::AuthorizationResponse() nsXPIDLCString password; nsXPIDLCString cachedPassword; - SetNewsFolder(); + SetNewsFolderAndMsgKey(); + if (m_newsFolder) { rv = m_newsFolder->GetGroupPassword(getter_Copies(cachedPassword)); } @@ -2899,7 +2860,7 @@ PRInt32 nsNNTPProtocol::PasswordResponse() /* If we're here because the host demanded authentication before we * even sent a single command, then jump back to the beginning of everything */ - rv = m_newsHost->GetPushAuth(&pushAuth); + rv = m_nntpServer->GetPushAuth(&pushAuth); if (!TestFlag(NNTP_READER_PERFORMED)) m_nextState = NNTP_SEND_MODE_READER; @@ -2918,16 +2879,16 @@ PRInt32 nsNNTPProtocol::PasswordResponse() m_nextState = SEND_FIRST_NNTP_COMMAND; #endif /* HAVE_PUSH_AUTH_AND_EXTENSIONS */ - // if we are posting, m_newsgroup will be null - if (!m_newsgroupList && m_newsgroup) { - nsXPIDLCString groupName; - rv = m_newsgroup->GetName(getter_Copies(groupName)); - if (NS_SUCCEEDED(rv)) { - rv = m_newsHost->GetNewsgroupList(groupName, getter_AddRefs(m_newsgroupList)); - } + // if we are posting, m_newsFolder will be null + if (!m_newsgroupList && m_newsFolder) { + m_newsgroupList = do_CreateInstance(NS_NNTPNEWSGROUPLIST_CONTRACTID, &rv); + if (NS_FAILED(rv)) return -1; + + rv = m_newsgroupList->Initialize(m_runningURL, m_newsFolder); + if (NS_FAILED(rv)) return -1; } if (m_newsgroupList) { - rv = m_newsgroupList->ResetXOVER(); + rv = m_newsgroupList->ResetXOVER(); } return(0); } @@ -3009,14 +2970,13 @@ PRInt32 nsNNTPProtocol::ProcessNewsgroups(nsIInputStream * inputStream, PRUint32 { ClearFlag(NNTP_PAUSE_FOR_READ); PRBool xactive=PR_FALSE; - rv = m_newsHost->QueryExtension("XACTIVE",&xactive); + rv = m_nntpServer->QueryExtension("XACTIVE",&xactive); if (NS_SUCCEEDED(rv) && xactive) { - char *groupName; - rv = m_newsHost->GetFirstGroupNeedingExtraInfo(&groupName); - if (NS_SUCCEEDED(rv) && m_newsgroup) - { - rv = m_newsHost->FindGroup(groupName, getter_AddRefs(m_newsgroup)); + nsXPIDLCString groupName; + rv = m_nntpServer->GetFirstGroupNeedingExtraInfo(getter_Copies(groupName)); + if (NS_SUCCEEDED(rv)) { + rv = m_nntpServer->FindGroup((const char *)groupName, getter_AddRefs(m_newsFolder)); NS_ASSERTION(NS_SUCCEEDED(rv), "FindGroup failed"); m_nextState = NNTP_LIST_XACTIVE; PR_LOG(NNTP,PR_LOG_ALWAYS,("listing xactive for %s", groupName)); @@ -3085,20 +3045,18 @@ PRInt32 nsNNTPProtocol::ProcessNewsgroups(nsIInputStream * inputStream, PRUint32 mBytesReceived += status; mBytesReceivedSinceLastStatusUpdate += status; #endif -#if 0 - m_newsHost->AddNewNewsgroup(line, oldest, youngest, flag, PR_FALSE); -#else + NS_ASSERTION(m_nntpServer, "no nntp incoming server"); if (m_nntpServer) { rv = m_nntpServer->AddNewsgroupToList(line); NS_ASSERTION(NS_SUCCEEDED(rv),"failed to add to subscribe ds"); } -#endif /* 0 */ + PRBool xactive=PR_FALSE; - rv = m_newsHost->QueryExtension("XACTIVE",&xactive); + rv = m_nntpServer->QueryExtension("XACTIVE",&xactive); if (NS_SUCCEEDED(rv) && xactive) { - m_newsHost->SetGroupNeedsExtraInfo(line, PR_TRUE); + m_nntpServer->SetGroupNeedsExtraInfo(line, PR_TRUE); } PR_FREEIF(line); @@ -3145,7 +3103,7 @@ static void ComputeRate(PRInt32 bytes, PRTime startTime, float *rate) // compute rate if (delta > 0) { - *rate = (bytes * RATE_CONSTANT) / delta; + *rate = (float) ((bytes * RATE_CONSTANT) / delta); } else { *rate = 0.0; @@ -3179,7 +3137,7 @@ PRInt32 nsNNTPProtocol::ReadNewsList(nsIInputStream * inputStream, PRUint32 leng if (line[0]=='.' && line[1]=='\0') { PRBool listpnames=PR_FALSE; - rv = m_newsHost->QueryExtension("LISTPNAMES",&listpnames); + rv = m_nntpServer->QueryExtension("LISTPNAMES",&listpnames); if (NS_SUCCEEDED(rv) && listpnames) m_nextState = NNTP_LIST_PRETTY_NAMES; else @@ -3260,9 +3218,6 @@ PRInt32 nsNNTPProtocol::ReadNewsList(nsIInputStream * inputStream, PRUint32 leng line[i] = 0; /* terminate group name */ /* store all the group names */ -#if 0 - m_newsHost->AddNewNewsgroup(line, 0, 0, "", PR_FALSE); -#else NS_ASSERTION(m_nntpServer, "no nntp incoming server"); if (m_nntpServer) { m_readNewsListCount++; @@ -3273,7 +3228,6 @@ PRInt32 nsNNTPProtocol::ReadNewsList(nsIInputStream * inputStream, PRUint32 leng else { rv = NS_ERROR_FAILURE; } -#endif /* 0 */ if (m_readNewsListCount == READ_NEWS_LIST_COUNT_MAX) { m_readNewsListCount = 0; @@ -3341,13 +3295,13 @@ PRInt32 nsNNTPProtocol::BeginReadXover() &m_firstPossibleArticle, &m_lastPossibleArticle); - /* We now know there is a summary line there; make sure it has the - right numbers in it. */ - rv = m_newsHost->DisplaySubscribedGroup(m_newsgroup, - m_firstPossibleArticle, - m_lastPossibleArticle, - count, PR_TRUE); + m_newsgroupList = do_CreateInstance(NS_NNTPNEWSGROUPLIST_CONTRACTID, &rv); + if (NS_FAILED(rv)) return -1; + rv = m_newsgroupList->Initialize(m_runningURL, m_newsFolder); + if (NS_FAILED(rv)) return -1; + + rv = m_newsFolder->UpdateSummaryFromNNTPInfo(m_firstPossibleArticle, m_lastPossibleArticle, count); if (NS_FAILED(rv)) return -1; m_numArticlesLoaded = 0; @@ -3366,14 +3320,6 @@ PRInt32 nsNNTPProtocol::FigureNextChunk() nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); if (m_firstArticle > 0) { - nsXPIDLCString groupName; - - rv = m_newsgroup->GetName(getter_Copies(groupName)); - - /* XXX - parse state stored in MSG_Pane cd->pane */ - if (NS_SUCCEEDED(rv)) - rv = m_newsHost->GetNewsgroupList(groupName, getter_AddRefs(m_newsgroupList)); - PR_LOG(NNTP,PR_LOG_ALWAYS,("add to known articles: %d - %d", m_firstArticle, m_lastArticle)); if (NS_SUCCEEDED(rv) && m_newsgroupList) { @@ -3392,32 +3338,26 @@ PRInt32 nsNNTPProtocol::FigureNextChunk() return 0; } - if (!m_newsgroupList) { - nsXPIDLCString groupName; - rv = m_newsgroup->GetName(getter_Copies(groupName)); - if (NS_SUCCEEDED(rv)) - rv = m_newsHost->GetNewsgroupList(groupName, getter_AddRefs(m_newsgroupList)); - } + NS_ASSERTION(m_newsgroupList, "yikes"); + if (!m_newsgroupList) return -1; - if (NS_SUCCEEDED(rv) && m_newsgroupList) { - PRBool getOldMessages = PR_FALSE; - if (m_runningURL) { - rv = m_runningURL->GetGetOldMessages(&getOldMessages); - if (NS_FAILED(rv)) return status; - } - rv = m_newsgroupList->SetGetOldMessages(getOldMessages); - if (NS_FAILED(rv)) return status; - - rv = m_newsgroupList->GetRangeOfArtsToDownload(m_msgWindow, - m_firstPossibleArticle, - m_lastPossibleArticle, - m_numArticlesWanted - - m_numArticlesLoaded, - &(m_firstArticle), - &(m_lastArticle), - &status); + PRBool getOldMessages = PR_FALSE; + if (m_runningURL) { + rv = m_runningURL->GetGetOldMessages(&getOldMessages); + if (NS_FAILED(rv)) return status; + } + rv = m_newsgroupList->SetGetOldMessages(getOldMessages); + if (NS_FAILED(rv)) return status; + + rv = m_newsgroupList->GetRangeOfArtsToDownload(m_msgWindow, + m_firstPossibleArticle, + m_lastPossibleArticle, + m_numArticlesWanted - + m_numArticlesLoaded, + &(m_firstArticle), + &(m_lastArticle), + &status); - } if (NS_FAILED(rv)) return status; @@ -3580,14 +3520,14 @@ PRInt32 nsNNTPProtocol::ProcessXover() PRInt32 status = 0; /* xover_parse_state stored in MSG_Pane cd->pane */ - if (!m_newsgroupList) { - return NS_ERROR_NULL_POINTER; - } + NS_ASSERTION(m_newsgroupList, "yikes"); + if (!m_newsgroupList) return -1; rv = m_newsgroupList->FinishXOVERLINE(0,&status); - if (NS_SUCCEEDED(rv) && status < 0) return status; + m_newsgroupList = nsnull; + m_nextState = NEWS_DONE; return(MK_DATA_LOADED); @@ -3635,6 +3575,8 @@ PRInt32 nsNNTPProtocol::ReadNewsgroupResponse() if(m_messageID) *m_messageID = '\0'; + m_key = nsMsgKey_None; + /* Give the message number to the header parser. */ rv = m_newsgroupList->ProcessNonXOVER(m_responseText); /* convert nsresult->status */ @@ -4094,7 +4036,7 @@ PRInt32 nsNNTPProtocol::DisplayNewsRCResponse() } else if (m_responseCode == MK_NNTP_RESPONSE_GROUP_NO_GROUP) { - m_newsHost->GroupNotFound(m_currentGroup, PR_FALSE); + m_nntpServer->GroupNotFound(m_currentGroup, PR_FALSE); } /* it turns out subscribe ui depends on getting this displaysubscribedgroup call, even if there was an error. @@ -4212,7 +4154,7 @@ PRInt32 nsNNTPProtocol::DoCancel() MSG_CompositionFields *fields = NULL; #endif - SetNewsFolder(); + SetNewsFolderAndMsgKey(); /* #### Should we do a more real check than this? If the POST command didn't respond with "MK_NNTP_RESPONSE_POST_SEND_NOW Ok", then it's not ready for us to throw a @@ -4272,7 +4214,7 @@ PRInt32 nsNNTPProtocol::DoCancel() Don't do this if server tells us it will validate user. DMB 3/19/97 */ PRBool cancelchk=PR_FALSE; - rv = m_newsHost->QueryExtension("CANCELCHK",&cancelchk); + rv = m_nntpServer->QueryExtension("CANCELCHK",&cancelchk); if (NS_SUCCEEDED(rv) && !cancelchk) { NNTP_LOG_NOTE("CANCELCHK not supported"); @@ -4397,13 +4339,11 @@ PRInt32 nsNNTPProtocol::DoCancel() if (!m_runningURL) return -1; - // delete the message from the db here. - nsMsgKey key = nsMsgKey_None; - rv = m_runningURL->GetMessageKey(&key); - NS_ASSERTION(NS_SUCCEEDED(rv) && m_newsFolder && (key != nsMsgKey_None), "need more to remove this message from the db"); - if ((key != nsMsgKey_None) && (m_newsFolder)) { - rv = m_newsFolder->RemoveMessage(key); + // delete the message from the db here. + NS_ASSERTION(NS_SUCCEEDED(rv) && m_newsFolder && (m_key != nsMsgKey_None), "need more to remove this message from the db"); + if ((m_key != nsMsgKey_None) && (m_newsFolder)) { + rv = m_newsFolder->RemoveMessage(m_key); } } @@ -4544,7 +4484,7 @@ PRInt32 nsNNTPProtocol::ListPrettyNames() char outputBuffer[OUTPUT_BUFFER_SIZE]; PRInt32 status = 0; - nsresult rv = m_newsgroup->GetName(getter_Copies(group_name)); + nsresult rv = m_newsFolder->GetAsciiName(getter_Copies(group_name)); PR_snprintf(outputBuffer, OUTPUT_BUFFER_SIZE, "LIST PRETTYNAMES %.512s" CRLF, @@ -4601,7 +4541,7 @@ PRInt32 nsNNTPProtocol::ListPrettyNamesResponse(nsIInputStream * inputStream, PR line[i] = 0; /* terminate group name */ if (i > 0) - m_newsHost->SetPrettyName(line,prettyName); + m_nntpServer->SetPrettyName(line, prettyName); PR_LOG(NNTP,PR_LOG_ALWAYS,("adding pretty name %s", prettyName)); } @@ -4621,9 +4561,10 @@ PRInt32 nsNNTPProtocol::ListPrettyNamesResponse(nsIInputStream * inputStream, PR PRInt32 nsNNTPProtocol::ListXActive() { nsXPIDLCString group_name; - nsresult rv; - rv = m_newsgroup->GetName(getter_Copies(group_name)); - // XXX: check rv? + nsresult rv; + rv = m_newsFolder->GetAsciiName(getter_Copies(group_name)); + if (NS_FAILED(rv)) return -1; + PRInt32 status = 0; char outputBuffer[OUTPUT_BUFFER_SIZE]; @@ -4699,17 +4640,12 @@ PRInt32 nsNNTPProtocol::ListXActiveResponse(nsIInputStream * inputStream, PRUint &m_lastPossibleArticle, flags); -#if 0 - m_newsHost->AddNewNewsgroup(line, - m_firstPossibleArticle, - m_lastPossibleArticle, flags, PR_TRUE); -#else + NS_ASSERTION(m_nntpServer, "no nntp incoming server"); if (m_nntpServer) { rv = m_nntpServer->AddNewsgroupToList(line); NS_ASSERTION(NS_SUCCEEDED(rv),"failed to add to subscribe ds"); } -#endif /* 0 */ /* we're either going to list prettynames first, or list all prettynames every time, so we won't care so much @@ -4725,19 +4661,22 @@ PRInt32 nsNNTPProtocol::ListXActiveResponse(nsIInputStream * inputStream, PRUint else { PRBool xactive=PR_FALSE; - rv = m_newsHost->QueryExtension("XACTIVE",&xactive); + rv = m_nntpServer->QueryExtension("XACTIVE",&xactive); if (m_typeWanted == NEW_GROUPS && NS_SUCCEEDED(rv) && xactive) { - nsCOMPtr old_newsgroup; - old_newsgroup = m_newsgroup; - char *groupName; + nsCOMPtr old_newsFolder; + old_newsFolder = m_newsFolder; + nsXPIDLCString groupName; - m_newsHost->GetFirstGroupNeedingExtraInfo(&groupName); - m_newsHost->FindGroup(groupName, getter_AddRefs(m_newsgroup)); + rv = m_nntpServer->GetFirstGroupNeedingExtraInfo(getter_Copies(groupName)); + if (NS_FAILED(rv)) return -1; + rv = m_nntpServer->FindGroup(groupName, getter_AddRefs(m_newsFolder)); + if (NS_FAILED(rv)) return -1; + // see if we got a different group - if (old_newsgroup && m_newsgroup && - (old_newsgroup != m_newsgroup)) + if (old_newsFolder && m_newsFolder && + (old_newsFolder.get() != m_newsFolder.get())) /* make sure we're not stuck on the same group */ { PR_LOG(NNTP,PR_LOG_ALWAYS,("listing xactive for %s", groupName)); @@ -4748,11 +4687,11 @@ PRInt32 nsNNTPProtocol::ListXActiveResponse(nsIInputStream * inputStream, PRUint } else { - m_newsgroup = null_nsCOMPtr(); + m_newsFolder = nsnull; } } PRBool listpname; - rv = m_newsHost->QueryExtension("LISTPNAME",&listpname); + rv = m_nntpServer->QueryExtension("LISTPNAME",&listpname); if (NS_SUCCEEDED(rv) && listpname) m_nextState = NNTP_LIST_PRETTY_NAMES; else @@ -4784,7 +4723,7 @@ PRInt32 nsNNTPProtocol::ListGroup() getter_AddRefs(m_articleList)); NS_ENSURE_SUCCESS(rv,rv); - rv = m_articleList->Initialize(m_newsHost, m_newsgroup); + rv = m_articleList->Initialize(m_newsFolder); NS_ENSURE_SUCCESS(rv,rv); nsCOMPtr mailnewsurl = do_QueryInterface(m_runningURL); @@ -4832,6 +4771,8 @@ PRInt32 nsNNTPProtocol::ListGroupResponse(nsIInputStream * inputStream, PRUint32 } else { + m_articleList->FinishAddingArticleKeys(); + m_articleList = nsnull; m_nextState = NEWS_DONE; /* ### dmb - don't really know */ ClearFlag(NNTP_PAUSE_FOR_READ); PR_FREEIF(line); @@ -5377,10 +5318,19 @@ nsresult nsNNTPProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp NS_IMETHODIMP nsNNTPProtocol::CloseConnection() { - SendData(nsnull, NNTP_CMD_QUIT); // this will cause OnStopRequest get called, which will call CloseSocket() + SendData(nsnull, NNTP_CMD_QUIT); // this will cause OnStopRequest get called, which will call CloseSocket() + // break some cycles - m_newsHost = nsnull; + m_newsgroupList = nsnull; m_nntpServer = nsnull; + m_newsFolder = nsnull; + + if (m_articleList) { + m_articleList->FinishAddingArticleKeys(); + m_articleList = nsnull; + } + + m_key = nsMsgKey_None; return NS_OK; } @@ -5408,15 +5358,9 @@ nsresult nsNNTPProtocol::CleanupAfterRunningUrl() if (m_newsgroupList) { int status; - /* XXX - how/when to Release() this? */ rv = m_newsgroupList->FinishXOVERLINE(0,&status); NS_ASSERTION(NS_SUCCEEDED(rv), "FinishXOVERLINE failed"); - } - else - { - /* XXX - state is stored in the newshost - should - we be releasing it here? */ - /* NS_RELEASE(m_newsgroup->GetNewsgroupList()); */ + m_newsgroupList = nsnull; } // clear out mem cache entry so we're not holding onto it. @@ -5492,7 +5436,7 @@ NS_IMETHODIMP nsNNTPProtocol::GetContentType(char * *aContentType) // otherwise do what we did before... - if (m_typeWanted != ARTICLE_WANTED && !m_currentGroup.IsEmpty() && + if (m_key == nsMsgKey_None && m_typeWanted != ARTICLE_WANTED && !m_currentGroup.IsEmpty() && // if it is an article url, it has a @ or %40 in it. m_currentGroup.FindChar('@') == kNotFound && m_currentGroup.Find("%40") == kNotFound) { *aContentType = nsCRT::strdup("x-application-newsgroup"); diff --git a/mozilla/mailnews/news/src/nsNNTPProtocol.h b/mozilla/mailnews/news/src/nsNNTPProtocol.h index 87ca654f68f..135ec81c67a 100644 --- a/mozilla/mailnews/news/src/nsNNTPProtocol.h +++ b/mozilla/mailnews/news/src/nsNNTPProtocol.h @@ -36,8 +36,6 @@ #include "nsINNTPNewsgroupList.h" #include "nsINNTPArticleList.h" -#include "nsINNTPHost.h" -#include "nsINNTPNewsgroup.h" #include "nsIMsgOfflineNewsState.h" #include "nsIMsgNewsFolder.h" #include "nsIMsgWindow.h" @@ -192,8 +190,6 @@ private: // News Event Sinks nsCOMPtr m_newsgroupList; nsCOMPtr m_articleList; - nsCOMPtr m_newsHost; - nsCOMPtr m_newsgroup; nsCOMPtr m_offlineNewsState; nsCOMPtr m_newsFolder; @@ -397,7 +393,7 @@ private: nsresult SetProgressStatus(const PRUnichar *aMessage); nsresult SetCheckingForNewNewsStatus(PRInt32 current, PRInt32 total); nsresult MarkCurrentMsgRead(); // marks the message corresponding to the currently running url read. - nsresult SetNewsFolder(); /* sets m_newsFolder, if not already set */ + nsresult SetNewsFolderAndMsgKey(); /* sets m_newsFolder (if not already set) and m_key from the running url */ nsresult CreateNewsFolderURI (const char *username, const char *hostname, const char *newsgroupname, char **uri); nsresult InitializeNewsFolderFromUri(const char *uri); void TimerCallback(); @@ -408,6 +404,8 @@ private: PRInt32 mBytesReceivedSinceLastStatusUpdate; PRTime m_startTime; PRInt32 mNumGroupsListed; + nsMsgKey m_key; + }; NS_BEGIN_EXTERN_C diff --git a/mozilla/mailnews/news/src/nsNewsDownloader.cpp b/mozilla/mailnews/news/src/nsNewsDownloader.cpp index 8cd8e49c95c..2537f207af6 100644 --- a/mozilla/mailnews/news/src/nsNewsDownloader.cpp +++ b/mozilla/mailnews/news/src/nsNewsDownloader.cpp @@ -33,8 +33,6 @@ // This file contains the news article download state machine. -static NS_DEFINE_CID(kNntpServiceCID, NS_NNTPSERVICE_CID); - // if pIds is not null, download the articles whose id's are passed in. Otherwise, // which articles to download is determined by nsNewsDownloader object, @@ -108,7 +106,7 @@ nsresult nsNewsDownloader::DownloadNext(PRBool firstTimeP) StartDownload(); m_wroteAnyP = PR_FALSE; - NS_WITH_SERVICE(nsINntpService, nntpService, kNntpServiceCID, &rv); + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID,&rv); NS_ENSURE_SUCCESS(rv, rv); return nntpService->FetchMessage(m_folder, m_keyToDownload, m_window, nsnull, this, nsnull); diff --git a/mozilla/mailnews/news/src/nsNewsFolder.cpp b/mozilla/mailnews/news/src/nsNewsFolder.cpp index 2be50c00707..58c84d8d60c 100644 --- a/mozilla/mailnews/news/src/nsNewsFolder.cpp +++ b/mozilla/mailnews/news/src/nsNewsFolder.cpp @@ -27,6 +27,7 @@ #include "prlog.h" #include "msgCore.h" // precompiled header... +#include "nntpCore.h" #include "nsNewsFolder.h" #include "nsMsgFolderFlags.h" @@ -71,12 +72,13 @@ #include "nsReadableUtils.h" #include "nsNewsDownloader.h" +#include "nsIStringBundle.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 static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); -static NS_DEFINE_CID(kNntpServiceCID, NS_NNTPSERVICE_CID); static NS_DEFINE_CID(kCNewsDB, NS_NEWSDB_CID); static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID); static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); @@ -100,7 +102,7 @@ static NS_DEFINE_CID(kNetSupportDialogCID, NS_NETSUPPORTDIALOG_CID); nsMsgNewsFolder::nsMsgNewsFolder(void) : nsMsgLineBuffer(nsnull, PR_FALSE), mExpungedBytes(0), mGettingNews(PR_FALSE), mInitialized(PR_FALSE), mOptionLines(""), mUnsubscribedNewsgroupLines(""), - m_downloadMessageForOfflineUse(PR_FALSE), mCachedNewsrcLine(nsnull), mGroupUsername(nsnull), mGroupPassword(nsnull) + m_downloadMessageForOfflineUse(PR_FALSE), mCachedNewsrcLine(nsnull), mGroupUsername(nsnull), mGroupPassword(nsnull), mAsciiName(nsnull) { MOZ_COUNT_CTOR(nsNewsFolder); // double count these for now. /* we're parsing the newsrc file, and the line breaks are platform specific. @@ -120,6 +122,7 @@ nsMsgNewsFolder::~nsMsgNewsFolder(void) PR_FREEIF(mCachedNewsrcLine); PR_FREEIF(mGroupUsername); PR_FREEIF(mGroupPassword); + PR_FREEIF(mAsciiName); } NS_IMPL_ADDREF_INHERITED(nsMsgNewsFolder, nsMsgDBFolder) @@ -902,30 +905,58 @@ NS_IMETHODIMP nsMsgNewsFolder::GetSizeOnDisk(PRUint32 *size) } /* this is news, so remember that DeleteMessage is really CANCEL */ -NS_IMETHODIMP nsMsgNewsFolder::DeleteMessages(nsISupportsArray *messages, - nsIMsgWindow *aMsgWindow, PRBool deleteStorage, - PRBool isMove) +NS_IMETHODIMP +nsMsgNewsFolder::DeleteMessages(nsISupportsArray *messages, nsIMsgWindow *aMsgWindow, + PRBool deleteStorage, PRBool isMove) { nsresult rv = NS_OK; + + NS_ENSURE_ARG_POINTER(messages); + NS_ENSURE_ARG_POINTER(aMsgWindow); + + PRUint32 count = 0; + rv = messages->Count(&count); + NS_ENSURE_SUCCESS(rv,rv); - if (!messages) { - // nothing to CANCEL - return NS_ERROR_NULL_POINTER; - } + if (count != 1) { + nsCOMPtr bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); - NS_WITH_SERVICE(nsINntpService, nntpService, kNntpServiceCID, &rv); + nsCOMPtr bundle; + rv = bundleService->CreateBundle(NEWS_MSGS_URL, nsnull, getter_AddRefs(bundle)); + NS_ENSURE_SUCCESS(rv, rv); + + nsXPIDLString alertText; + rv = bundle->GetStringFromName(NS_LITERAL_STRING("onlyCancelOneMessage"), getter_Copies(alertText)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr dialog; + rv = aMsgWindow->GetPromptDialog(getter_AddRefs(dialog)); + NS_ENSURE_SUCCESS(rv,rv); + + if (dialog) { + rv = dialog->Alert(nsnull, (const PRUnichar *) alertText); + NS_ENSURE_SUCCESS(rv,rv); + } + // return failure, since the cancel failed + return NS_ERROR_FAILURE; + } - if (NS_SUCCEEDED(rv) && nntpService) { - nsXPIDLCString hostname; - rv = GetHostname(getter_Copies(hostname)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); - nsXPIDLCString newsgroupname; - rv = GetAsciiName(getter_Copies(newsgroupname)); - if (NS_FAILED(rv)) return rv; - - rv = nntpService->CancelMessages((const char *)hostname, (const char *)newsgroupname, messages, nsnull /* consumer */, nsnull, aMsgWindow, nsnull); - } + nsCOMPtr msgSupports = getter_AddRefs(messages->ElementAt(0)); + nsCOMPtr msgHdr(do_QueryInterface(msgSupports)); + + nsXPIDLCString messageUri; + rv = GetUriForMsg(msgHdr, getter_Copies(messageUri)); + NS_ENSURE_SUCCESS(rv,rv); + + nsCAutoString cancelUrl((const char *)messageUri); + cancelUrl += "?cancel"; + + rv = nntpService->CancelMessage(cancelUrl.get(), nsnull /* consumer */, nsnull, aMsgWindow, nsnull); + NS_ENSURE_SUCCESS(rv,rv); return rv; } @@ -957,8 +988,8 @@ nsresult nsMsgNewsFolder::GetNewsMessages(nsIMsgWindow *aMsgWindow, PRBool aGetO return NS_OK; } - NS_WITH_SERVICE(nsINntpService, nntpService, kNntpServiceCID, &rv); - if (NS_FAILED(rv)) return rv; + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); nsCOMPtr nntpServer; rv = GetNntpServer(getter_AddRefs(nntpServer)); @@ -1595,15 +1626,21 @@ nsMsgNewsFolder::GetAsciiName(char **asciiName) { nsresult rv; - if (!asciiName) return NS_ERROR_NULL_POINTER; + NS_ENSURE_ARG_POINTER(asciiName); + if (!mAsciiName) { + nsXPIDLString name; + rv = GetName(getter_Copies(name)); + NS_ENSURE_SUCCESS(rv,rv); - nsXPIDLString name; - rv = GetName(getter_Copies(name)); - if (NS_FAILED(rv)) return rv; + // convert to ASCII + nsCAutoString tmpStr; + tmpStr.AssignWithConversion(name); - nsCAutoString tmpStr; - tmpStr.AssignWithConversion(name); - *asciiName = nsCRT::strdup((const char *)tmpStr); + mAsciiName = nsCRT::strdup(tmpStr.get()); + if (!mAsciiName) return NS_ERROR_OUT_OF_MEMORY; + } + + *asciiName = nsCRT::strdup(mAsciiName); if (!*asciiName) return NS_ERROR_OUT_OF_MEMORY; return NS_OK; @@ -1753,4 +1790,3 @@ NS_IMETHODIMP nsMsgNewsFolder::Compact(nsIUrlListener *aListener) } return rv; } - diff --git a/mozilla/mailnews/news/src/nsNewsFolder.h b/mozilla/mailnews/news/src/nsNewsFolder.h index f68ebf08958..31bd38eae92 100644 --- a/mozilla/mailnews/news/src/nsNewsFolder.h +++ b/mozilla/mailnews/news/src/nsNewsFolder.h @@ -134,6 +134,9 @@ protected: char *mGroupUsername; char *mGroupPassword; + // the name of the newsgroup. + char *mAsciiName; + private: nsresult CreateNewsgroupUsernameUrlForSignon(const char *inUriStr, char **result); nsresult CreateNewsgroupPasswordUrlForSignon(const char *inUriStr, char **result); diff --git a/mozilla/mailnews/news/src/nsNntpIncomingServer.cpp b/mozilla/mailnews/news/src/nsNntpIncomingServer.cpp index b2f2f857ed7..011835ad6c8 100644 --- a/mozilla/mailnews/news/src/nsNntpIncomingServer.cpp +++ b/mozilla/mailnews/news/src/nsNntpIncomingServer.cpp @@ -61,7 +61,6 @@ #define HOSTINFO_FILE_BUFFER_SIZE 1024 static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); -static NS_DEFINE_CID(kNntpServiceCID, NS_NNTPSERVICE_CID); static NS_DEFINE_CID(kSubscribableServerCID, NS_SUBSCRIBABLESERVER_CID); NS_IMPL_ADDREF_INHERITED(nsNntpIncomingServer, nsMsgIncomingServer) @@ -92,6 +91,9 @@ nsNntpIncomingServer::nsNntpIncomingServer() : nsMsgLineBuffer(nsnull, PR_FALSE) mUniqueId = 0; mPushAuth = PR_FALSE; mHasSeenBeginGroups = PR_FALSE; + mPostingAllowed = PR_FALSE; + mLastUpdatedTime = 0; + SetupNewsrcSaveTimer(); } @@ -566,16 +568,12 @@ NS_IMETHODIMP nsNntpIncomingServer::PerformExpand(nsIMsgWindow *aMsgWindow) { nsresult rv; -#ifdef DEBUG_NEWS - printf("PerformExpand for nntp\n"); -#endif - nsCOMPtr nntpService = do_GetService(kNntpServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - if (!nntpService) return NS_ERROR_FAILURE; + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); rv = nntpService->UpdateCounts(this, aMsgWindow); - if (NS_FAILED(rv)) return rv; + NS_ENSURE_SUCCESS(rv,rv); return NS_OK; } @@ -965,9 +963,8 @@ nsNntpIncomingServer::StartPopulating(nsIMsgWindow *aMsgWindow, PRBool aForceToS rv = SetShowFullName(PR_TRUE); if (NS_FAILED(rv)) return rv; - nsCOMPtr nntpService = do_GetService(kNntpServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - if (!nntpService) return NS_ERROR_FAILURE; + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); mHostInfoLoaded = PR_FALSE; mVersion = INVALID_VERSION; @@ -1387,3 +1384,153 @@ nsNntpIncomingServer::ForgetPassword() return return_rv; } +NS_IMETHODIMP +nsNntpIncomingServer::GetSupportsExtensions(PRBool *aSupportsExtensions) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::SetSupportsExtensions(PRBool aSupportsExtensions) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::AddExtension(const char *extension) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::QueryExtension(const char *extension, PRBool *result) +{ +#ifdef DEBUG_seth + printf("no extension support yet\n"); +#endif + *result = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsNntpIncomingServer::GetPostingAllowed(PRBool *aPostingAllowed) +{ + *aPostingAllowed = mPostingAllowed; + return NS_OK; +} + +NS_IMETHODIMP +nsNntpIncomingServer::SetPostingAllowed(PRBool aPostingAllowed) +{ + mPostingAllowed = aPostingAllowed; + return NS_OK; +} + +NS_IMETHODIMP +nsNntpIncomingServer::GetPushAuth(PRBool *aPushAuth) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::SetPushAuth(PRBool aPushAuth) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::GetLastUpdatedTime(PRUint32 *aLastUpdatedTime) +{ + *aLastUpdatedTime = mLastUpdatedTime; + return NS_OK; +} + +NS_IMETHODIMP +nsNntpIncomingServer::SetLastUpdatedTime(PRUint32 aLastUpdatedTime) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::AddPropertyForGet(const char *name, const char *value) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::QueryPropertyForGet(const char *name, char **value) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::AddSearchableGroup(const char *name) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::QuerySearchableGroup(const char *name, PRBool *result) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::AddSearchableHeader(const char *name) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::QuerySearchableHeader(const char *name, PRBool *result) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::FindGroup(const char *name, nsIMsgNewsFolder **result) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::GetFirstGroupNeedingExtraInfo(char **result) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::SetGroupNeedsExtraInfo(const char *name, PRBool needsExtraInfo) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP +nsNntpIncomingServer::GroupNotFound(const char *name, PRBool opening) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNntpIncomingServer::SetPrettyName(const char *name, const char *prettyName) +{ + NS_ASSERTION(0,"not implemented"); + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/mozilla/mailnews/news/src/nsNntpIncomingServer.h b/mozilla/mailnews/news/src/nsNntpIncomingServer.h index 046625d841e..563bffb823a 100644 --- a/mozilla/mailnews/news/src/nsNntpIncomingServer.h +++ b/mozilla/mailnews/news/src/nsNntpIncomingServer.h @@ -102,7 +102,9 @@ private: PRTime mFirstNewDate; PRInt32 mUniqueId; PRBool mPushAuth; + PRUint32 mLastUpdatedTime; PRInt32 mVersion; + PRBool mPostingAllowed; nsCOMPtr mNewsrcSaveTimer; nsCOMPtr mMsgWindow; diff --git a/mozilla/mailnews/news/src/nsNntpService.cpp b/mozilla/mailnews/news/src/nsNntpService.cpp index cb32a316b44..1d2910d1aa5 100644 --- a/mozilla/mailnews/news/src/nsNntpService.cpp +++ b/mozilla/mailnews/news/src/nsNntpService.cpp @@ -35,7 +35,6 @@ #include "nsNewsUtils.h" #include "nsNewsDatabase.h" #include "nsMsgDBCID.h" -#include "nsNNTPNewsgroup.h" #include "nsMsgBaseCID.h" #include "nsMsgNewsCID.h" #include "nsIPref.h" @@ -68,7 +67,6 @@ static NS_DEFINE_CID(kCNntpUrlCID, NS_NNTPURL_CID); static NS_DEFINE_CID(kCNewsDB, NS_NEWSDB_CID); -static NS_DEFINE_CID(kCNNTPNewsgroupCID, NS_NNTPNEWSGROUP_CID); static NS_DEFINE_CID(kCNNTPNewsgroupPostCID, NS_NNTPNEWSGROUPPOST_CID); static NS_DEFINE_CID(kCPrefServiceCID, NS_PREF_CID); static NS_DEFINE_CID(kMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID); @@ -112,48 +110,34 @@ nsNntpService::SaveMessageToDisk(const char *aMessageURI, nsIMsgWindow *aMsgWindow) { nsresult rv = NS_OK; - if (!aMessageURI) - return NS_ERROR_NULL_POINTER; - -#ifdef DEBUG_NEWS - printf("nsNntpService::SaveMessageToDisk(%s,...)\n",aMessageURI); -#endif - - nsCAutoString uri; - nsCAutoString newsgroupName; - nsMsgKey key = nsMsgKey_None; - - if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen) == 0) { - rv = ConvertNewsMessageURI2NewsURI(aMessageURI, uri, newsgroupName, nsnull, &key); - NS_ENSURE_SUCCESS(rv,rv); - } - else { + NS_ENSURE_ARG_POINTER(aMessageURI); + + // double check it is a news_message:/ uri + if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen)) { rv = NS_ERROR_UNEXPECTED; NS_ENSURE_SUCCESS(rv,rv); } - // now create a url with this uri spec - nsCOMPtr myuri; + nsCOMPtr url; - rv = ConstructNntpUrl(uri, newsgroupName, key, aUrlListener, aMsgWindow, getter_AddRefs(myuri)); - if (NS_SUCCEEDED(rv)) - { - nsCOMPtr nntpUrl = do_QueryInterface(myuri); - nsCOMPtr msgUrl = do_QueryInterface(myuri); - nntpUrl->SetNewsAction(nsINntpUrl::ActionSaveMessageToDisk); - if (msgUrl) - { + rv = ConstructNntpUrl(aMessageURI, aUrlListener, aMsgWindow, getter_AddRefs(url)); + NS_ENSURE_SUCCESS(rv,rv); + + nsCOMPtr nntpUrl = do_QueryInterface(url); + nsCOMPtr msgUrl = do_QueryInterface(url); + nntpUrl->SetNewsAction(nsINntpUrl::ActionSaveMessageToDisk); + if (msgUrl) { msgUrl->SetMessageFile(aFile); - msgUrl->SetAddDummyEnvelope(aAddDummyEnvelope); - msgUrl->SetCanonicalLineEnding(canonicalLineEnding); - } + msgUrl->SetAddDummyEnvelope(aAddDummyEnvelope); + msgUrl->SetCanonicalLineEnding(canonicalLineEnding); + } - rv = RunNewsUrl(myuri, nsnull, nsnull); - } + rv = RunNewsUrl(url, nsnull, nsnull); + NS_ENSURE_SUCCESS(rv,rv); if (aURL) { - *aURL = myuri; + *aURL = url; NS_IF_ADDREF(*aURL); } @@ -167,34 +151,25 @@ nsNntpService::DisplayMessage(const char* aMessageURI, nsISupports * aDisplayCon nsresult rv = NS_OK; NS_ENSURE_ARG_POINTER(aMessageURI); - nsCAutoString uri; - nsCAutoString newsgroupName; - nsMsgKey key = nsMsgKey_None; - nsCOMPtr newsFolder; - if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen) == 0) { - rv = ConvertNewsMessageURI2NewsURI(aMessageURI, uri, newsgroupName, getter_AddRefs(newsFolder), &key); - NS_ENSURE_SUCCESS(rv,rv); - } - else { -#ifdef DEBUG_seth - printf("todo: if we get here, make sure uri really a news article url (example: news://host/aa@bb\n"); -#endif - uri = aMessageURI; - } - - - // now create a url with this uri spec - nsCOMPtr myuri; + nsCAutoString uri(aMessageURI); // rhp: If we are displaying this message for the purposes of printing, append // the magic operand. if (mPrintingOperation) uri.Append("?header=print"); - rv = ConstructNntpUrl(uri, newsgroupName, key, aUrlListener, aMsgWindow, getter_AddRefs(myuri)); + nsCOMPtr url; + rv = ConstructNntpUrl(uri.get(), aUrlListener, aMsgWindow, getter_AddRefs(url)); + NS_ENSURE_SUCCESS(rv,rv); + + nsCOMPtr folder; + nsMsgKey key = nsMsgKey_None; + rv = DecomposeNewsMessageURI(uri.get(), getter_AddRefs(folder), &key); + NS_ENSURE_SUCCESS(rv,rv); + if (NS_SUCCEEDED(rv)) { - nsCOMPtr nntpUrl (do_QueryInterface(myuri)); + nsCOMPtr nntpUrl (do_QueryInterface(url)); nsCOMPtr msgUrl (do_QueryInterface(nntpUrl)); msgUrl->SetMsgWindow(aMsgWindow); nntpUrl->SetNewsAction(nsINntpUrl::ActionDisplayArticle); @@ -205,10 +180,10 @@ nsNntpService::DisplayMessage(const char* aMessageURI, nsISupports * aDisplayCon PRBool shouldStoreMsgOffline = PR_FALSE; PRBool hasMsgOffline = PR_FALSE; - if (newsFolder) + if (folder) { - nsCOMPtr folder = do_QueryInterface(newsFolder); - if (folder) + nsCOMPtr newsFolder = do_QueryInterface(folder); + if (newsFolder) { folder->ShouldStoreMsgOffline(key, &shouldStoreMsgOffline); folder->HasMsgOffline(key, &hasMsgOffline); @@ -226,7 +201,6 @@ nsNntpService::DisplayMessage(const char* aMessageURI, nsISupports * aDisplayCon } } newsFolder->SetSaveArticleOffline(shouldStoreMsgOffline); - } // now is where our behavior differs....if the consumer is the docshell then we want to @@ -242,15 +216,15 @@ nsNntpService::DisplayMessage(const char* aMessageURI, nsISupports * aDisplayCon docShell->CreateLoadInfo(getter_AddRefs(loadInfo)); loadInfo->SetLoadType(nsIDocShellLoadInfo::loadLink); } - rv = docShell->LoadURI(myuri, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE); + rv = docShell->LoadURI(url, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE); } else { - rv = RunNewsUrl(myuri, aMsgWindow, aDisplayConsumer); + rv = RunNewsUrl(url, aMsgWindow, aDisplayConsumer); } } if (aURL) { - *aURL = myuri; + *aURL = url; NS_IF_ADDREF(*aURL); } @@ -263,15 +237,11 @@ nsNntpService::FetchMessage(nsIMsgFolder *newsFolder, nsMsgKey key, nsIMsgWindow nsresult rv = NS_OK; NS_ENSURE_ARG_POINTER(newsFolder); - nsCString uri; - nsCString newsgroupName; - nsXPIDLCString msgUri; // now create a url for the message nsCOMPtr msgNewsFolder = do_QueryInterface(newsFolder); if (!msgNewsFolder) return NS_ERROR_INVALID_ARG; -// msgNewsFolder->GetAsciiName(getter_Copies(newsgroupName)); nsCOMPtr db; nsCOMPtr msgHdr; @@ -281,24 +251,23 @@ nsNntpService::FetchMessage(nsIMsgFolder *newsFolder, nsMsgKey key, nsIMsgWindow if (!NS_SUCCEEDED(rv) || !msgHdr) return NS_ERROR_INVALID_ARG; - newsFolder->GetUriForMsg(msgHdr, getter_Copies(msgUri)); - nsCOMPtr myuri; + nsXPIDLCString uri; + newsFolder->GetUriForMsg(msgHdr, getter_Copies(uri)); + nsCOMPtr url; - rv = ConvertNewsMessageURI2NewsURI(msgUri, uri, newsgroupName, nsnull, &key); - - rv = ConstructNntpUrl(uri, newsgroupName, key, aUrlListener, aMsgWindow, getter_AddRefs(myuri)); + rv = ConstructNntpUrl((const char *)uri, aUrlListener, aMsgWindow, getter_AddRefs(url)); if (NS_SUCCEEDED(rv)) { - nsCOMPtr nntpUrl (do_QueryInterface(myuri)); + nsCOMPtr nntpUrl (do_QueryInterface(url)); nsCOMPtr msgUrl (do_QueryInterface(nntpUrl)); msgUrl->SetMsgWindow(aMsgWindow); nntpUrl->SetNewsAction(nsINntpUrl::ActionDisplayArticle); - rv = RunNewsUrl(myuri, aMsgWindow, aConsumer); + rv = RunNewsUrl(url, aMsgWindow, aConsumer); } if (aURL) { - *aURL = myuri; + *aURL = url; NS_IF_ADDREF(*aURL); } @@ -331,16 +300,13 @@ NS_IMETHODIMP nsNntpService::OpenAttachment(const char *aContentType, NS_IMETHODIMP nsNntpService::GetUrlForUri(const char *aMessageURI, nsIURI **aURL, nsIMsgWindow *aMsgWindow) { nsresult rv = NS_OK; - nsCAutoString uri; - nsCAutoString newsgroupName; - nsMsgKey key = nsMsgKey_None; - + + NS_ENSURE_ARG_POINTER(aMessageURI); + + // double check that it is a news_message:/ uri if (PL_strncmp(aMessageURI, kNewsMessageRootURI, kNewsMessageRootURILen) == 0) { - rv = ConvertNewsMessageURI2NewsURI(aMessageURI, uri, newsgroupName, nsnull, &key); - NS_ENSURE_SUCCESS(rv,rv); - - rv = ConstructNntpUrl(uri, newsgroupName, key, nsnull, aMsgWindow, aURL); + rv = ConstructNntpUrl(aMessageURI, nsnull, aMsgWindow, aURL); NS_ENSURE_SUCCESS(rv,rv); } else { @@ -352,6 +318,23 @@ NS_IMETHODIMP nsNntpService::GetUrlForUri(const char *aMessageURI, nsIURI **aURL } +NS_IMETHODIMP +nsNntpService::DecomposeNewsURI(const char *uri, nsIMsgFolder **folder, nsMsgKey *aMsgKey) +{ + nsresult rv; + + if (nsCRT::strncmp(uri, kNewsMessageRootURI, kNewsMessageRootURILen) == 0) { + rv = DecomposeNewsMessageURI(uri, folder, aMsgKey); + NS_ENSURE_SUCCESS(rv,rv); + } + else { + rv = GetFolderFromUri(uri, folder); + NS_ENSURE_SUCCESS(rv,rv); + *aMsgKey = nsMsgKey_None; + } + return rv; +} + nsresult nsNntpService::DecomposeNewsMessageURI(const char * aMessageURI, nsIMsgFolder ** aFolder, nsMsgKey *aMsgKey) { @@ -361,19 +344,32 @@ nsNntpService::DecomposeNewsMessageURI(const char * aMessageURI, nsIMsgFolder ** nsresult rv = NS_OK; nsCAutoString folderURI; + rv = nsParseNewsMessageURI(aMessageURI, folderURI, aMsgKey); NS_ENSURE_SUCCESS(rv,rv); + rv = GetFolderFromUri(folderURI, aFolder); + NS_ENSURE_SUCCESS(rv,rv); + + return NS_OK; +} + +nsresult +nsNntpService::GetFolderFromUri(const char *uri, nsIMsgFolder **folder) +{ + nsresult rv; nsCOMPtr rdf = do_GetService("@mozilla.org/rdf/rdf-service;1",&rv); NS_ENSURE_SUCCESS(rv,rv); + // if this is a message uri, we need + // m_currentGroup.FindChar('@') == kNotFound && m_currentGroup.Find("%40") == kNotFound) { + nsCOMPtr res; - rv = rdf->GetResource(folderURI, getter_AddRefs(res)); + rv = rdf->GetResource(uri, getter_AddRefs(res)); NS_ENSURE_SUCCESS(rv,rv); - rv = res->QueryInterface(NS_GET_IID(nsIMsgFolder), (void **) aFolder); + rv = res->QueryInterface(NS_GET_IID(nsIMsgFolder), (void **)folder); NS_ENSURE_SUCCESS(rv,rv); - return NS_OK; } @@ -632,14 +628,6 @@ nsNntpService::SetUpNntpUrlForPosting(nsINntpUrl *nntpUrl, const char *newsgroup host = "news"; } - // 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; - } - *newsUrlSpec = PR_smprintf("%s/%s",kNewsRootURI,(const char *)host); if (!*newsUrlSpec) return NS_ERROR_FAILURE; @@ -826,8 +814,8 @@ nsNntpService::PostMessage(nsIFileSpec *fileToPost, const char *newsgroupsNames, return rv; } -nsresult nsNntpService::ConstructNntpUrl(const char * urlString, const char * newsgroupName, nsMsgKey key, nsIUrlListener *aUrlListener, - nsIMsgWindow * aMsgWindow, nsIURI ** aUrl) +nsresult +nsNntpService::ConstructNntpUrl(const char * urlString, nsIUrlListener *aUrlListener, nsIMsgWindow * aMsgWindow, nsIURI ** aUrl) { nsCOMPtr nntpUrl; nsresult rv = NS_OK; @@ -841,26 +829,6 @@ nsresult nsNntpService::ConstructNntpUrl(const char * urlString, const char * ne msgUrl->SetUri(urlString); mailnewsurl->SetSpec(urlString); - if (newsgroupName != "") { - nsCOMPtr newsgroup; - rv = nsComponentManager::CreateInstance(kCNNTPNewsgroupCID, nsnull, NS_GET_IID(nsINNTPNewsgroup), getter_AddRefs(newsgroup)); - if (NS_FAILED(rv) || !newsgroup) return rv; - - rv = newsgroup->Initialize(newsgroupName, nsnull /* set */, PR_TRUE); - if (NS_FAILED(rv)) return rv; - - rv = nntpUrl->SetNewsgroup(newsgroup); - if (NS_FAILED(rv)) return rv; - - // if we are running a news url to display a message, these - // will be used later, to mark the message as read after we finish loading - rv = nntpUrl->SetMessageKey(key); - if (NS_FAILED(rv)) return rv; - - rv = nntpUrl->SetNewsgroupName((char *) newsgroupName); - if (NS_FAILED(rv)) return rv; - } - if (aUrlListener) // register listener if there is one... mailnewsurl->RegisterListener(aUrlListener); @@ -1066,168 +1034,74 @@ NS_IMETHODIMP nsNntpService::GetNewNews(nsINntpIncomingServer *nntpServer, const { if (!uri) return NS_ERROR_NULL_POINTER; -#ifdef DEBUG_NEWS - printf("nsNntpService::GetNewNews(%s)\n", uri); -#endif - NS_LOCK_INSTANCE(); nsresult rv = NS_OK; - nsXPIDLCString nntpHostName; nsCOMPtr server; server = do_QueryInterface(nntpServer); - - // convert normal host to nntp host. - // XXX - this doesn't handle QI failing very well - if (server) { - // load up required server information - server->GetHostName(getter_Copies(nntpHostName)); - } -#ifdef DEBUG_NEWS - else { - printf("server == nsnull\n"); - } -#endif - -#ifdef DEBUG_NEWS - if (nntpHostName) { - printf("get news from news://%s\n", (const char *) nntpHostName); - } - else { - printf("nntpHostName is null\n"); - } -#endif + + /* double check that it is a "news:/" url */ + if (nsCRT::strncmp(uri, kNewsRootURI, kNewsRootURILen) == 0) { + nsCOMPtr aUrl; + rv = ConstructNntpUrl(uri, aUrlListener, aMsgWindow, getter_AddRefs(aUrl)); + if (NS_FAILED(rv)) return rv; - nsCAutoString uriStr(uri); - nsCAutoString newsgroupName; - - NS_ASSERTION((uriStr.Find(kNewsRootURI) == 0), "uriStr didn't start with news:/"); - if (uriStr.Find(kNewsRootURI) == 0) { - // uriStr looks like this: - // "news://news.mcom.com/mcom.linux" - // or this: - // "news://sspitzer@news.mcom.com/mcom.linux" - - PRInt32 atPos = uriStr.FindChar('@'); - if (atPos == -1) { - uriStr.Right(newsgroupName, uriStr.Length() - kNewsRootURILen /* for news:/ */ - 1 /* for the slash */ - PL_strlen(nntpHostName) /* for the hostname */ -1 /* for the next slash */); - } - else { - uriStr.Right(newsgroupName, uriStr.Length() - atPos /* for "news://" */ -1 /* for the @ */ - PL_strlen(nntpHostName) /* for the hostname */ -1 /* for the next slash */); - } - - nsCOMPtr aUrl; - rv = ConstructNntpUrl(uriStr, newsgroupName, nsMsgKey_None, aUrlListener, aMsgWindow, getter_AddRefs(aUrl)); - if (NS_FAILED(rv)) return rv; - nsCOMPtr nntpUrl = do_QueryInterface(aUrl); - if (nntpUrl) { - rv = nntpUrl->SetNewsAction(nsINntpUrl::ActionGetNewNews); - if (NS_FAILED(rv)) return rv; + nsCOMPtr nntpUrl = do_QueryInterface(aUrl); + if (nntpUrl) { + rv = nntpUrl->SetNewsAction(nsINntpUrl::ActionGetNewNews); + if (NS_FAILED(rv)) return rv; - rv = nntpUrl->SetGetOldMessages(aGetOld); - if (NS_FAILED(rv)) return rv; - } - nsCOMPtr mailNewsUrl = do_QueryInterface(aUrl); - if (mailNewsUrl) - { - mailNewsUrl->SetUpdatingFolder(PR_TRUE); - mailNewsUrl->SetMsgWindow(aMsgWindow); - } + rv = nntpUrl->SetGetOldMessages(aGetOld); + if (NS_FAILED(rv)) return rv; + } + + nsCOMPtr mailNewsUrl = do_QueryInterface(aUrl); + if (mailNewsUrl) { + mailNewsUrl->SetUpdatingFolder(PR_TRUE); + mailNewsUrl->SetMsgWindow(aMsgWindow); + } rv = RunNewsUrl(aUrl, aMsgWindow, nsnull); - if (_retval) - { - *_retval = aUrl; - NS_IF_ADDREF(*_retval); - } + if (_retval) { + *_retval = aUrl; + NS_IF_ADDREF(*_retval); + } } - else + else { + NS_ASSERTION(0,"not a news:/ url"); rv = NS_ERROR_FAILURE; + } NS_UNLOCK_INSTANCE(); return rv; } -NS_IMETHODIMP nsNntpService::CancelMessages(const char *hostname, const char *newsgroupname, nsISupportsArray *messages, nsISupports * aConsumer, nsIUrlListener * aUrlListener, nsIMsgWindow *aMsgWindow, nsIURI ** aURL) +NS_IMETHODIMP +nsNntpService::CancelMessage(const char *uri, nsISupports * aConsumer, nsIUrlListener * aUrlListener, nsIMsgWindow *aMsgWindow, nsIURI ** aURL) { - nsresult rv = NS_OK; - PRUint32 count = 0; + nsresult rv; + NS_ENSURE_ARG_POINTER(uri); - NS_ENSURE_ARG(aMsgWindow); - - if (!hostname) return NS_ERROR_NULL_POINTER; - if (PL_strlen(hostname) == 0) return NS_ERROR_FAILURE; - - nsCOMPtr dialog; - aMsgWindow->GetPromptDialog(getter_AddRefs(dialog)); - NS_ENSURE_TRUE(dialog, NS_ERROR_FAILURE); - - if (!messages) { - nsAutoString alertText; alertText.AssignWithConversion("No articles are selected."); - if (dialog) - rv = dialog->Alert(nsnull, alertText.GetUnicode()); - - return NS_ERROR_NULL_POINTER; - } - - rv = messages->Count(&count); - if (NS_FAILED(rv)) { -#ifdef DEBUG_NEWS - printf("Count failed\n"); -#endif - return rv; - } - - if (count != 1) { - nsAutoString alertText; alertText.AssignWithConversion("You can only cancel one article at a time."); - if (dialog) - rv = dialog->Alert(nsnull, alertText.GetUnicode()); - return NS_ERROR_FAILURE; - } - - nsMsgKey key; - nsXPIDLCString messageId; - - nsCOMPtr msgSupports = getter_AddRefs(messages->ElementAt(0)); - nsCOMPtr message(do_QueryInterface(msgSupports)); - if (message) { - rv = message->GetMessageKey(&key); - if (NS_FAILED(rv)) return rv; - rv = message->GetMessageId(getter_Copies(messageId)); - if (NS_FAILED(rv)) return rv; - } - else { - return NS_ERROR_FAILURE; - } - - nsCAutoString urlStr; - urlStr += kNewsRootURI; - urlStr += "/"; - urlStr += hostname; - urlStr += "/"; - urlStr += (const char*)messageId; - urlStr += "?cancel"; - -#ifdef DEBUG_NEWS - printf("attempt to cancel the message (key,ID,cancel url): (%d,%s,%s)\n", key, (const char *)messageId, (const char *)urlStr); -#endif /* DEBUG_NEWS */ - - nsCAutoString newsgroupNameStr(newsgroupname); nsCOMPtr url; - rv = ConstructNntpUrl((const char *)urlStr, newsgroupNameStr, key, aUrlListener, aMsgWindow, getter_AddRefs(url)); - if (NS_FAILED(rv)) return rv; - nsCOMPtr nntpUrl = do_QueryInterface(url); - if (nntpUrl) - nntpUrl->SetNewsAction(nsINntpUrl::ActionCancelArticle); - rv = RunNewsUrl(url, aMsgWindow, aConsumer); + // the url should have "?cancel" already on it + rv = ConstructNntpUrl(uri, aUrlListener, aMsgWindow, getter_AddRefs(url)); + NS_ENSURE_SUCCESS(rv,rv); - if (aURL) - { - *aURL = url; - NS_IF_ADDREF(*aURL); + nsCOMPtr nntpUrl = do_QueryInterface(url); + if (nntpUrl) { + nntpUrl->SetNewsAction(nsINntpUrl::ActionCancelArticle); } + + rv = RunNewsUrl(url, aMsgWindow, aConsumer); + NS_ENSURE_SUCCESS(rv,rv); + + if (aURL) { + *aURL = url; + NS_IF_ADDREF(*aURL); + } + return rv; } @@ -1447,28 +1321,31 @@ NS_IMETHODIMP nsNntpService::Search(nsIMsgSearchSession *aSearchSession, nsIMsgW { nsCOMPtr uri; nsXPIDLCString serverUri; - nsXPIDLString newsgroupName; - rv = server->GetServerURI(getter_Copies(serverUri)); - if (NS_FAILED(rv)) return rv; - aMsgFolder->GetName(getter_Copies(newsgroupName)); - if (NS_FAILED(rv)) return rv; + nsXPIDLCString newsgroupName; - nsCString searchUrl(NS_STATIC_CAST(const char *, serverUri)); - nsCString asciiNewsgroupName; - asciiNewsgroupName.AssignWithConversion(newsgroupName); - searchUrl.Append(aSearchUri); + rv = server->GetServerURI(getter_Copies(serverUri)); + NS_ENSURE_SUCCESS(rv,rv); + + nsCOMPtr newsFolder = do_QueryInterface(aMsgFolder, &rv); + NS_ENSURE_SUCCESS(rv,rv); + + rv = newsFolder->GetAsciiName(getter_Copies(newsgroupName)); + NS_ENSURE_SUCCESS(rv,rv); + + nsCAutoString searchUrl((const char *)serverUri); + searchUrl += aSearchUri; nsCOMPtr urlListener = do_QueryInterface(aSearchSession); - rv = ConstructNntpUrl(searchUrl.GetBuffer(), asciiNewsgroupName.GetBuffer(), nsMsgKey_None, urlListener, aMsgWindow, getter_AddRefs(uri)); - if (NS_FAILED(rv)) return rv; + rv = ConstructNntpUrl(searchUrl.get(), urlListener, aMsgWindow, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv,rv); nsCOMPtr msgurl (do_QueryInterface(uri)); if (msgurl) msgurl->SetSearchSession(aSearchSession); - // run the url to update the counts - rv = RunNewsUrl(uri, nsnull, nsnull); - if (NS_FAILED(rv)) return rv; + // run the url to update the counts + rv = RunNewsUrl(uri, nsnull, nsnull); + NS_ENSURE_SUCCESS(rv,rv); } return rv; } @@ -1492,7 +1369,7 @@ nsNntpService::UpdateCounts(nsINntpIncomingServer *aNntpServer, nsIMsgWindow *aM rv = server->GetServerURI(getter_Copies(serverUri)); if (NS_FAILED(rv)) return rv; - rv = ConstructNntpUrl((const char *)serverUri, "", nsMsgKey_None, nsnull, aMsgWindow, getter_AddRefs(uri)); + rv = ConstructNntpUrl((const char *)serverUri, nsnull, aMsgWindow, getter_AddRefs(uri)); if (NS_FAILED(rv)) return rv; // run the url to update the counts @@ -1506,10 +1383,8 @@ NS_IMETHODIMP nsNntpService::GetListOfGroupsOnServer(nsINntpIncomingServer *aNntpServer, nsIMsgWindow *aMsgWindow) { nsresult rv; -#ifdef DEBUG_NEWS - printf("in GetListOfGroupsOnServer()\n"); -#endif - if (!aNntpServer) return NS_ERROR_NULL_POINTER; + + NS_ENSURE_ARG_POINTER(aNntpServer); nsCOMPtr uri; nsCOMPtr server = do_QueryInterface(aNntpServer, &rv); @@ -1526,7 +1401,7 @@ nsNntpService::GetListOfGroupsOnServer(nsINntpIncomingServer *aNntpServer, nsIMs nsCOMPtr listener = do_QueryInterface(aNntpServer, &rv); if (NS_FAILED(rv)) return rv; if (!listener) return NS_ERROR_FAILURE; - rv = ConstructNntpUrl((const char *)uriStr, "", nsMsgKey_None, listener, aMsgWindow, getter_AddRefs(uri)); + rv = ConstructNntpUrl((const char *)uriStr, listener, aMsgWindow, getter_AddRefs(uri)); if (NS_FAILED(rv)) return rv; // now run the url to add the rest of the groups diff --git a/mozilla/mailnews/news/src/nsNntpService.h b/mozilla/mailnews/news/src/nsNntpService.h index 0e3de297f81..c6e357fe334 100644 --- a/mozilla/mailnews/news/src/nsNntpService.h +++ b/mozilla/mailnews/news/src/nsNntpService.h @@ -76,11 +76,13 @@ protected: nsresult 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, nsIMsgWindow * aMsgWindow, nsIURI ** aUrl); + nsresult ConstructNntpUrl(const char * urlString, nsIUrlListener *aUrlListener, nsIMsgWindow * aMsgWindow, nsIURI ** aUrl); nsresult CreateNewsAccount(const char *username, const char *hostname, PRBool isSecure, PRInt32 port, nsIMsgIncomingServer **server); nsresult GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTPProtocol **aProtocol); // a convience routine to run news urls nsresult RunNewsUrl (nsIURI * aUrl, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer); + // a convience routine to go from folder uri to msg folder + nsresult GetFolderFromUri(const char *uri, nsIMsgFolder **folder); static PRBool findNewsServerWithGroup(nsISupports *aElement, void *data); nsresult DecomposeNewsMessageURI(const char * aMessageURI, nsIMsgFolder ** aFolder, nsMsgKey *aMsgKey); diff --git a/mozilla/mailnews/news/src/nsNntpUrl.cpp b/mozilla/mailnews/news/src/nsNntpUrl.cpp index a8812eb18ce..a2ad3401d9b 100644 --- a/mozilla/mailnews/news/src/nsNntpUrl.cpp +++ b/mozilla/mailnews/news/src/nsNntpUrl.cpp @@ -40,23 +40,20 @@ #include "nsXPIDLString.h" #include "nsIMsgDatabase.h" #include "nsMsgDBCID.h" +#include "nsMsgNewsCID.h" #include "nsIRDFService.h" #include "rdf.h" #include "nsIMsgFolder.h" - +#include "nsINntpService.h" +#include "nsIMsgMessageService.h" static NS_DEFINE_CID(kCNewsDB, NS_NEWSDB_CID); nsNntpUrl::nsNntpUrl() { // nsINntpUrl specific code... - m_newsHost = nsnull; - m_articleList = nsnull; - m_newsgroup = nsnull; m_offlineNews = nsnull; - m_newsgroupList = nsnull; m_newsgroupPost = nsnull; - m_messageKey = nsMsgKey_None; m_newsAction = nsINntpUrl::ActionGetNewNews; m_addDummyEnvelope = PR_FALSE; m_canonicalLineEnding = PR_FALSE; @@ -66,11 +63,7 @@ nsNntpUrl::nsNntpUrl() nsNntpUrl::~nsNntpUrl() { - NS_IF_RELEASE(m_newsHost); - NS_IF_RELEASE(m_articleList); - NS_IF_RELEASE(m_newsgroup); NS_IF_RELEASE(m_offlineNews); - NS_IF_RELEASE(m_newsgroupList); NS_IF_RELEASE(m_newsgroupPost); } @@ -115,81 +108,6 @@ NS_IMETHODIMP nsNntpUrl::SetNewsAction(nsNewsAction aNewsAction) return NS_OK; } -nsresult nsNntpUrl::SetNntpHost (nsINNTPHost * newsHost) -{ - NS_LOCK_INSTANCE(); - if (newsHost) - { - NS_IF_RELEASE(m_newsHost); - m_newsHost = newsHost; - NS_ADDREF(m_newsHost); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - -nsresult nsNntpUrl::GetNntpHost (nsINNTPHost ** newsHost) -{ - NS_LOCK_INSTANCE(); - if (newsHost) - { - *newsHost = m_newsHost; - NS_IF_ADDREF(m_newsHost); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - -nsresult nsNntpUrl::SetNntpArticleList (nsINNTPArticleList * articleList) -{ - NS_LOCK_INSTANCE(); - if (articleList) - { - NS_IF_RELEASE(m_articleList); - m_articleList = articleList; - NS_ADDREF(m_articleList); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - -nsresult nsNntpUrl::GetNntpArticleList (nsINNTPArticleList ** articleList) -{ - NS_LOCK_INSTANCE(); - if (articleList) - { - *articleList = m_articleList; - NS_IF_ADDREF(m_articleList); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - -nsresult nsNntpUrl::SetNewsgroup (nsINNTPNewsgroup * newsgroup) -{ - NS_LOCK_INSTANCE(); - if (newsgroup) - { - NS_IF_RELEASE(m_newsgroup); - m_newsgroup = newsgroup; - NS_ADDREF(m_newsgroup); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - -nsresult nsNntpUrl::GetNewsgroup (nsINNTPNewsgroup ** newsgroup) -{ - NS_LOCK_INSTANCE(); - if (newsgroup) - { - *newsgroup = m_newsgroup; - NS_IF_ADDREF(m_newsgroup); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - nsresult nsNntpUrl::SetOfflineNewsState (nsIMsgOfflineNewsState * offlineNews) { NS_LOCK_INSTANCE(); @@ -215,61 +133,20 @@ nsresult nsNntpUrl::GetOfflineNewsState (nsIMsgOfflineNewsState ** offlineNews) return NS_OK; } -nsresult nsNntpUrl::SetNewsgroupList (nsINNTPNewsgroupList * newsgroupList) -{ - NS_LOCK_INSTANCE(); - if (newsgroupList) - { - NS_IF_RELEASE(m_newsgroupList); - m_newsgroupList = newsgroupList; - NS_IF_ADDREF(m_newsgroupList); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - -nsresult nsNntpUrl::GetNewsgroupList (nsINNTPNewsgroupList ** newsgroupList) -{ - NS_LOCK_INSTANCE(); - if (newsgroupList) - { - *newsgroupList = m_newsgroupList; - NS_IF_ADDREF(m_newsgroupList); - } - NS_UNLOCK_INSTANCE(); - return NS_OK; -} - NS_IMETHODIMP nsNntpUrl::SetUri(const char * aURI) { - mURI= aURI; + mURI = aURI; return NS_OK; } // from nsIMsgMessageUrl NS_IMETHODIMP nsNntpUrl::GetUri(char ** aURI) -{ - nsresult rv = NS_OK; - // if we have been given a uri to associate with this url, then use it - // otherwise try to reconstruct a URI on the fly.... - - if (!mURI.IsEmpty()) - *aURI = mURI.ToNewCString(); - else - { - nsXPIDLCString spec; - GetSpec(getter_Copies(spec)); - char * baseMessageURI; - nsCreateNewsBaseMessageURI(spec, &baseMessageURI); - nsCAutoString uriStr; - - rv = nsBuildNewsMessageURI(baseMessageURI, m_messageKey, uriStr); - nsCRT::free(baseMessageURI); - if (NS_FAILED(rv)) return rv; - *aURI = uriStr.ToNewCString(); - return NS_OK; - } +{ + NS_ENSURE_ARG_POINTER(aURI); + nsresult rv = NS_OK; + *aURI = mURI.ToNewCString(); + if (!*aURI) return NS_ERROR_OUT_OF_MEMORY; return rv; } @@ -318,88 +195,21 @@ nsresult nsNntpUrl::GetMessageToPost(nsINNTPNewsgroupPost **aPost) NS_IMETHODIMP nsNntpUrl::GetMessageHeader(nsIMsgDBHdr ** aMsgHdr) { - nsresult rv = NS_OK; - nsFileSpec pathResult; - - if (!aMsgHdr) return NS_ERROR_NULL_POINTER; - - if (!((const char *)m_newsgroupName)) return NS_ERROR_FAILURE; - - nsXPIDLCString hostName; - rv = GetHost(getter_Copies(hostName)); - if (NS_FAILED(rv)) return rv; - - nsXPIDLCString userName; - rv = GetPreHost(getter_Copies(userName)); - if (NS_FAILED(rv)) return rv; - - nsCString newsgroupURI(kNewsMessageRootURI); - newsgroupURI.Append("/"); - if (userName && (userName != (const char *)"")) { - newsgroupURI.Append(userName); - newsgroupURI.Append("@"); - } - newsgroupURI.Append(hostName); - newsgroupURI.Append("/"); - newsgroupURI.Append((const char *)m_newsgroupName); - - rv = nsNewsURI2Path(kNewsMessageRootURI, newsgroupURI.GetBuffer(), pathResult); - if (NS_FAILED(rv)) { - return rv; - } - - nsCOMPtr newsDBFactory; - nsCOMPtr newsDB; - - rv = nsComponentManager::CreateInstance(kCNewsDB, nsnull, NS_GET_IID(nsIMsgDatabase), getter_AddRefs(newsDBFactory)); - if (NS_FAILED(rv) || (!newsDBFactory)) { - return rv; - } - - nsCOMPtr dbFileSpec; - NS_NewFileSpecWithSpec(pathResult, getter_AddRefs(dbFileSpec)); - rv = newsDBFactory->Open(dbFileSpec, PR_TRUE, PR_FALSE, getter_AddRefs(newsDB)); - - if (NS_FAILED(rv) || (!newsDB)) { - return rv; - } - - rv = newsDB->GetMsgHdrForKey(m_messageKey, aMsgHdr); - if (NS_FAILED(rv) || (!aMsgHdr)) { - return rv; - } + nsresult rv; - return NS_OK; -} + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); -NS_IMETHODIMP nsNntpUrl::SetNewsgroupName(const char * aNewsgroupName) -{ - m_newsgroupName = aNewsgroupName; - return NS_OK; -} +#ifdef DEBUG_seth + printf("GetMessageHeader for %s\n",mURI.get()); +#endif + nsCOMPtr msgService = do_QueryInterface(nntpService, &rv); + NS_ENSURE_SUCCESS(rv,rv); -NS_IMETHODIMP nsNntpUrl::GetNewsgroupName(char ** aNewsgroupName) -{ - NS_ENSURE_ARG_POINTER(aNewsgroupName); - - *aNewsgroupName = nsCRT::strdup((const char *)m_newsgroupName); - - if (!aNewsgroupName) { - return NS_ERROR_OUT_OF_MEMORY; - } - return NS_OK; -} - -NS_IMETHODIMP nsNntpUrl::SetMessageKey(nsMsgKey aKey) -{ - m_messageKey = aKey; - return NS_OK; -} - -NS_IMETHODIMP nsNntpUrl::GetMessageKey(nsMsgKey * aKey) -{ - *aKey = m_messageKey; - return NS_OK; + rv = msgService->MessageURIToMsgHdr(mURI.get(), aMsgHdr); + NS_ENSURE_SUCCESS(rv,rv); + + return NS_OK; } NS_IMETHODIMP nsNntpUrl::IsUrlType(PRUint32 type, PRBool *isType) @@ -433,64 +243,14 @@ nsNntpUrl::SetOriginalSpec(const char *aSpec) nsresult nsNntpUrl::GetMsgFolder(nsIMsgFolder **msgFolder) { - /* - well, not proud of this. but it will all get fixed when - the news code gets the beating it deserves. + nsresult rv; + nsCOMPtr nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv,rv); - ideally, we'd keep a weak reference to the current news folder - and just use that to determine the char set, but for now - we'll just get the folder from the url we are running. - - this code takes the current uri, which is for a news message - and turns it into a news folder uri, - and then get the folder for that URI, and the ask the folder - for it's charset.... - */ - - nsresult rv; - nsXPIDLCString uriStr; - rv = GetUri(getter_Copies(uriStr)); - NS_ENSURE_SUCCESS(rv,rv); - - nsCOMPtr uri = do_CreateInstance("@mozilla.org/network/standard-url;1", &rv); - NS_ENSURE_SUCCESS(rv,rv); - - rv = uri->SetSpec((const char *)uriStr); - NS_ENSURE_SUCCESS(rv,rv); - - // XXX todo? - // could the url already be a folder url? - // - // get the path, check for @ or %40. if has them, - // this is an article url, and we need to replace - // the path with the newsgroup name. - // for now, assume it is always an article url - - if (!((const char *)m_newsgroupName)) { - NS_ASSERTION(NS_ERROR_FAILURE,"no group name"); - return NS_ERROR_FAILURE; - } - - nsCAutoString groupPath("/"); - groupPath += m_newsgroupName; - - rv = uri->SetPath((const char *)groupPath); - NS_ENSURE_SUCCESS(rv,rv); - - rv = uri->GetSpec(getter_Copies(uriStr)); - NS_ENSURE_SUCCESS(rv,rv); - - nsCOMPtr rdfService = do_GetService(NS_RDF_CONTRACTID "/rdf-service;1", &rv); - NS_ENSURE_SUCCESS(rv,rv); - - nsCOMPtr resource; - rv = rdfService->GetResource((const char *)uriStr, getter_AddRefs(resource)); - NS_ENSURE_SUCCESS(rv,rv); - - rv = resource->QueryInterface(NS_GET_IID(nsIMsgFolder), (void**) msgFolder); - NS_ENSURE_SUCCESS(rv,rv); - - return rv; + nsMsgKey msgKey; + rv = nntpService->DecomposeNewsURI(mURI.get(), msgFolder, &msgKey); + NS_ENSURE_SUCCESS(rv,rv); + return NS_OK; } NS_IMETHODIMP diff --git a/mozilla/mailnews/news/src/nsNntpUrl.h b/mozilla/mailnews/news/src/nsNntpUrl.h index ac7dac8c815..f36e3967a3c 100644 --- a/mozilla/mailnews/news/src/nsNntpUrl.h +++ b/mozilla/mailnews/news/src/nsNntpUrl.h @@ -59,13 +59,7 @@ protected: nsresult GetMsgFolder(nsIMsgFolder **msgFolder); /* NNTP specific event sinks */ - nsINNTPHost * m_newsHost; - nsINNTPArticleList * m_articleList; - nsINNTPNewsgroup * m_newsgroup; nsIMsgOfflineNewsState* m_offlineNews; - nsINNTPNewsgroupList * m_newsgroupList; - nsMsgKey m_messageKey; - nsCString m_newsgroupName; nsCString mURI; // the RDF URI associated with this url. nsString mCharsetOverride; // used by nsIMsgI18NUrl... PRBool m_getOldMessages;