mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-27 19:07:31 +09:00
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
This commit is contained in:
parent
23e0d82436
commit
e400f4130a
1564 changed files with 510348 additions and 0 deletions
27
mailnews/news/src/moz.build
Normal file
27
mailnews/news/src/moz.build
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
SOURCES += [
|
||||
'nsNewsDownloadDialogArgs.cpp',
|
||||
'nsNewsDownloader.cpp',
|
||||
'nsNewsFolder.cpp',
|
||||
'nsNewsUtils.cpp',
|
||||
'nsNNTPArticleList.cpp',
|
||||
'nsNntpIncomingServer.cpp',
|
||||
'nsNntpMockChannel.cpp',
|
||||
'nsNNTPNewsgroupList.cpp',
|
||||
'nsNNTPNewsgroupPost.cpp',
|
||||
'nsNNTPProtocol.cpp',
|
||||
'nsNntpService.cpp',
|
||||
'nsNntpUrl.cpp',
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsNewsAutoCompleteSearch.js',
|
||||
'nsNewsAutoCompleteSearch.manifest',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'mail'
|
||||
|
||||
163
mailnews/news/src/nntpCore.h
Normal file
163
mailnews/news/src/nntpCore.h
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _NNTPCore_H__
|
||||
#define _NNTPCore_H__
|
||||
|
||||
#define NEWS_MSGS_URL "chrome://messenger/locale/news.properties"
|
||||
|
||||
// The following string constants are protocol strings. I'm defining them as macros here
|
||||
// so I don't have to sprinkle all of the strings throughout the protocol.
|
||||
#define NNTP_CMD_LIST_EXTENSIONS "LIST EXTENSIONS" CRLF
|
||||
#define NNTP_CMD_MODE_READER "MODE READER" CRLF
|
||||
#define NNTP_CMD_LIST_SEARCHES "LIST SEARCHES" CRLF
|
||||
#define NNTP_CMD_LIST_SEARCH_FIELDS "LIST SRCHFIELDS" CRLF
|
||||
#define NNTP_CMD_GET_PROPERTIES "GET" CRLF
|
||||
#define NNTP_CMD_LIST_SUBSCRIPTIONS "LIST SUBSCRIPTIONS" CRLF
|
||||
#define NNTP_CMD_POST "POST" CRLF
|
||||
#define NNTP_CMD_QUIT "QUIT" CRLF
|
||||
|
||||
// end of protocol strings
|
||||
|
||||
#define MK_NNTP_RESPONSE_HELP 100
|
||||
|
||||
#define MK_NNTP_RESPONSE_POSTING_ALLOWED 200
|
||||
#define MK_NNTP_RESPONSE_POSTING_DENIED 201
|
||||
|
||||
#define MK_NNTP_RESPONSE_DISCONTINUED 400
|
||||
|
||||
#define MK_NNTP_RESPONSE_COMMAND_UNKNOWN 500
|
||||
#define MK_NNTP_RESPONSE_SYNTAX_ERROR 501
|
||||
#define MK_NNTP_RESPONSE_PERMISSION_DENIED 502
|
||||
#define MK_NNTP_RESPONSE_SERVER_ERROR 503
|
||||
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_BOTH 220
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_HEAD 221
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_BODY 222
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_NONE 223
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_NO_GROUP 412
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_NO_CURRENT 420
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_NONEXIST 423
|
||||
#define MK_NNTP_RESPONSE_ARTICLE_NOTFOUND 430
|
||||
|
||||
#define MK_NNTP_RESPONSE_GROUP_SELECTED 211
|
||||
#define MK_NNTP_RESPONSE_GROUP_NO_GROUP 411
|
||||
|
||||
#define MK_NNTP_RESPONSE_IHAVE_OK 235
|
||||
#define MK_NNTP_RESPONSE_IHAVE_ARTICLE 335
|
||||
#define MK_NNTP_RESPONSE_IHAVE_NOT_WANTED 435
|
||||
#define MK_NNTP_RESPONSE_IHAVE_FAILED 436
|
||||
#define MK_NNTP_RESPONSE_IHAVE_REJECTED 437
|
||||
|
||||
#define MK_NNTP_RESPONSE_LAST_OK 223
|
||||
#define MK_NNTP_RESPONSE_LAST_NO_GROUP 412
|
||||
#define MK_NNTP_RESPONSE_LAST_NO_CURRENT 420
|
||||
#define MK_NNTP_RESPONSE_LAST_NO_ARTICLE 422
|
||||
|
||||
#define MK_NNTP_RESPONSE_LIST_OK 215
|
||||
|
||||
#define MK_NNTP_RESPONSE_NEWGROUPS_OK 231
|
||||
|
||||
#define MK_NNTP_RESPONSE_NEWNEWS_OK 230
|
||||
|
||||
#define MK_NNTP_RESPONSE_NEXT_OK 223
|
||||
#define MK_NNTP_RESPONSE_NEXT_NO_GROUP 412
|
||||
#define MK_NNTP_RESPONSE_NEXT_NO_CURRENT 420
|
||||
#define MK_NNTP_RESPONSE_NEXT_NO_ARTICLE 421
|
||||
|
||||
#define MK_NNTP_RESPONSE_POST_OK 240
|
||||
#define MK_NNTP_RESPONSE_POST_SEND_NOW 340
|
||||
#define MK_NNTP_RESPONSE_POST_DENIED 440
|
||||
#define MK_NNTP_RESPONSE_POST_FAILED 441
|
||||
|
||||
#define MK_NNTP_RESPONSE_QUIT_OK 205
|
||||
|
||||
#define MK_NNTP_RESPONSE_SLAVE_OK 202
|
||||
|
||||
#define MK_NNTP_RESPONSE_CHECK_NO_ARTICLE 238
|
||||
#define MK_NNTP_RESPONSE_CHECK_NO_ACCEPT 400
|
||||
#define MK_NNTP_RESPONSE_CHECK_LATER 431
|
||||
#define MK_NNTP_RESPONSE_CHECK_DONT_SEND 438
|
||||
#define MK_NNTP_RESPONSE_CHECK_DENIED 480
|
||||
#define MK_NNTP_RESPONSE_CHECK_ERROR 500
|
||||
|
||||
#define MK_NNTP_RESPONSE_XHDR_OK 221
|
||||
#define MK_NNTP_RESPONSE_XHDR_NO_GROUP 412
|
||||
#define MK_NNTP_RESPONSE_XHDR_NO_CURRENT 420
|
||||
#define MK_NNTP_RESPONSE_XHDR_NO_ARTICLE 430
|
||||
#define MK_NNTP_RESPONSE_XHDR_DENIED 502
|
||||
|
||||
#define MK_NNTP_RESPONSE_XOVER_OK 224
|
||||
#define MK_NNTP_RESPONSE_XOVER_NO_GROUP 412
|
||||
#define MK_NNTP_RESPONSE_XOVER_NO_CURRENT 420
|
||||
#define MK_NNTP_RESPONSE_XOVER_DENIED 502
|
||||
|
||||
#define MK_NNTP_RESPONSE_XPAT_OK 221
|
||||
#define MK_NNTP_RESPONSE_XPAT_NO_ARTICLE 430
|
||||
#define MK_NNTP_RESPONSE_XPAT_DENIED 502
|
||||
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_OK 281
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_CONT 381
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_REQUIRE 480
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_REJECT 482
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_DENIED 502
|
||||
|
||||
#define MK_NNTP_RESPONSE_
|
||||
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_SIMPLE_OK 250
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_SIMPLE_CONT 350
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_SIMPLE_REQUIRE 450
|
||||
#define MK_NNTP_RESPONSE_AUTHINFO_SIMPLE_REJECT 452
|
||||
|
||||
#define MK_NNTP_RESPONSE_TYPE_INFO 1
|
||||
#define MK_NNTP_RESPONSE_TYPE_OK 2
|
||||
#define MK_NNTP_RESPONSE_TYPE_CONT 3
|
||||
#define MK_NNTP_RESPONSE_TYPE_CANNOT 4
|
||||
#define MK_NNTP_RESPONSE_TYPE_ERROR 5
|
||||
|
||||
#define MK_NNTP_RESPONSE_TYPE(x) (x/100)
|
||||
|
||||
// the following used to be defined in allxpstr.h. Until we find a new values for these,
|
||||
// I'm defining them here because I don't want to link against xplib.lib...(mscott)
|
||||
|
||||
#define MK_DATA_LOADED 1
|
||||
#define MK_EMPTY_NEWS_LIST -227
|
||||
#define MK_INTERRUPTED -201
|
||||
#define MK_MALFORMED_URL_ERROR -209
|
||||
#define MK_NEWS_ERROR_FMT -430
|
||||
#define MK_NNTP_CANCEL_CONFIRM -426
|
||||
#define MK_NNTP_CANCEL_DISALLOWED -427
|
||||
#define MK_NNTP_NOT_CANCELLED -429
|
||||
#define MK_OUT_OF_MEMORY -207
|
||||
#define XP_CONFIRM_SAVE_NEWSGROUPS -1
|
||||
#define XP_HTML_ARTICLE_EXPIRED -1
|
||||
#define XP_HTML_NEWS_ERROR -1
|
||||
#define XP_PROGRESS_READ_NEWSGROUPINFO 1
|
||||
#define XP_PROGRESS_RECEIVE_ARTICLE 1
|
||||
#define XP_PROGRESS_RECEIVE_LISTARTICLES 1
|
||||
#define XP_PROGRESS_RECEIVE_NEWSGROUP 1
|
||||
#define XP_PROGRESS_SORT_ARTICLES 1
|
||||
#define XP_PROGRESS_READ_NEWSGROUP_COUNTS 1
|
||||
#define XP_THERMO_PERCENT_FORM 1
|
||||
#define XP_PROMPT_ENTER_USERNAME 1
|
||||
#define MK_NNTP_AUTH_FAILED -260
|
||||
#define MK_NNTP_ERROR_MESSAGE -304
|
||||
#define MK_NNTP_NEWSGROUP_SCAN_ERROR -305
|
||||
#define MK_NNTP_SERVER_ERROR -217
|
||||
#define MK_NNTP_SERVER_NOT_CONFIGURED -307
|
||||
#define MK_TCP_READ_ERROR -252
|
||||
#define MK_TCP_WRITE_ERROR -236
|
||||
#define MK_NNTP_CANCEL_ERROR -428
|
||||
#define XP_CONNECT_NEWS_HOST_CONTACTED_WAITING_FOR_REPLY 1
|
||||
#define XP_PLEASE_ENTER_A_PASSWORD_FOR_NEWS_SERVER_ACCESS 1
|
||||
#define XP_GARBAGE_COLLECTING 1
|
||||
#define XP_MESSAGE_SENT_WAITING_NEWS_REPLY 1
|
||||
#define MK_MSG_DELIV_NEWS 1
|
||||
#define MK_MSG_COLLABRA_DISABLED 1
|
||||
#define MK_MSG_EXPIRE_NEWS_ARTICLES 1
|
||||
#define MK_MSG_HTML_IMAP_NO_CACHED_BODY 1
|
||||
#define MK_MSG_CANT_MOVE_FOLDER 1
|
||||
|
||||
#endif /* NNTPCore_H__ */
|
||||
104
mailnews/news/src/nsNNTPArticleList.cpp
Normal file
104
mailnews/news/src/nsNNTPArticleList.cpp
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h" // precompiled header...
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsNNTPArticleList.h"
|
||||
#include "nsIMsgFolder.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsMsgKeyArray.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNNTPArticleList, nsINNTPArticleList)
|
||||
|
||||
nsNNTPArticleList::nsNNTPArticleList()
|
||||
{
|
||||
}
|
||||
|
||||
nsNNTPArticleList::~nsNNTPArticleList()
|
||||
{
|
||||
if (m_newsDB) {
|
||||
m_newsDB->Commit(nsMsgDBCommitType::kSessionCommit);
|
||||
m_newsDB->Close(true);
|
||||
m_newsDB = nullptr;
|
||||
}
|
||||
|
||||
m_newsFolder = nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPArticleList::Initialize(nsIMsgNewsFolder *newsFolder)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ENSURE_ARG_POINTER(newsFolder);
|
||||
|
||||
m_dbIndex = 0;
|
||||
|
||||
m_newsFolder = newsFolder;
|
||||
|
||||
nsCOMPtr <nsIMsgFolder> folder = do_QueryInterface(m_newsFolder, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = folder->GetMsgDatabase(getter_AddRefs(m_newsDB));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if (!m_newsDB) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
RefPtr<nsMsgKeyArray> keys = new nsMsgKeyArray;
|
||||
rv = m_newsDB->ListAllKeys(keys);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
keys->Sort();
|
||||
m_idsInDB.AppendElements(keys->m_keys);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPArticleList::AddArticleKey(nsMsgKey key)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
m_idsOnServer.AppendElement(key);
|
||||
#endif
|
||||
|
||||
if (m_dbIndex < m_idsInDB.Length())
|
||||
{
|
||||
nsMsgKey idInDBToCheck = m_idsInDB[m_dbIndex];
|
||||
// if there are keys in the database that aren't in the newsgroup
|
||||
// on the server, remove them. We probably shouldn't do this if
|
||||
// we have a copy of the article offline.
|
||||
// We'll add to m_idsDeleted for now and remove the id later
|
||||
while (idInDBToCheck < key)
|
||||
{
|
||||
m_idsDeleted.AppendElement(idInDBToCheck);
|
||||
if (m_dbIndex >= m_idsInDB.Length())
|
||||
break;
|
||||
idInDBToCheck = m_idsInDB[++m_dbIndex];
|
||||
}
|
||||
if (idInDBToCheck == key)
|
||||
m_dbIndex++;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPArticleList::FinishAddingArticleKeys()
|
||||
{
|
||||
// if the last n messages in the group are cancelled, they won't have gotten removed
|
||||
// so we have to go and remove them now.
|
||||
if (m_dbIndex < m_idsInDB.Length())
|
||||
m_idsDeleted.AppendElements(&m_idsInDB[m_dbIndex],
|
||||
m_idsInDB.Length() - m_dbIndex);
|
||||
|
||||
if (m_idsDeleted.Length())
|
||||
m_newsFolder->RemoveMessages(m_idsDeleted);
|
||||
|
||||
#ifdef DEBUG
|
||||
// make sure none of the deleted turned up on the idsOnServer list
|
||||
for (uint32_t i = 0; i < m_idsDeleted.Length(); i++) {
|
||||
NS_ASSERTION(!m_idsOnServer.Contains((nsMsgKey)m_idsDeleted[i]),
|
||||
"a deleted turned up on the idsOnServer list");
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
40
mailnews/news/src/nsNNTPArticleList.h
Normal file
40
mailnews/news/src/nsNNTPArticleList.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNNTPArticleList_h___
|
||||
#define nsNNTPArticleList_h___
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsINNTPArticleList.h"
|
||||
#include "nsIMsgNewsFolder.h"
|
||||
#include "nsIMsgDatabase.h"
|
||||
#include "MailNewsTypes.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsNNTPArticleList : public nsINNTPArticleList
|
||||
{
|
||||
public:
|
||||
nsNNTPArticleList();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINNTPARTICLELIST
|
||||
|
||||
protected:
|
||||
virtual ~nsNNTPArticleList();
|
||||
|
||||
nsTArray<nsMsgKey> m_idsInDB;
|
||||
|
||||
#ifdef DEBUG
|
||||
nsTArray<nsMsgKey> m_idsOnServer;
|
||||
#endif
|
||||
nsTArray<nsMsgKey> m_idsDeleted;
|
||||
|
||||
nsCOMPtr <nsIMsgNewsFolder> m_newsFolder;
|
||||
nsCOMPtr <nsIMsgDatabase> m_newsDB;
|
||||
|
||||
uint32_t m_dbIndex;
|
||||
};
|
||||
|
||||
#endif /* nsNNTPArticleList_h___ */
|
||||
1332
mailnews/news/src/nsNNTPNewsgroupList.cpp
Normal file
1332
mailnews/news/src/nsNNTPNewsgroupList.cpp
Normal file
File diff suppressed because it is too large
Load diff
124
mailnews/news/src/nsNNTPNewsgroupList.h
Normal file
124
mailnews/news/src/nsNNTPNewsgroupList.h
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/*
|
||||
* formerly listngst.h
|
||||
* This class should ultimately be part of a news group listing
|
||||
* state machine - either by inheritance or delegation.
|
||||
* Currently, a folder pane owns one and libnet news group listing
|
||||
* related messages get passed to this object.
|
||||
*/
|
||||
#ifndef nsNNTPNewsgroupListState_h___
|
||||
#define nsNNTPNewsgroupListState_h___
|
||||
|
||||
#include "nsINNTPNewsgroupList.h"
|
||||
#include "nsIMsgNewsFolder.h"
|
||||
#include "nsIMsgDatabase.h"
|
||||
#include "nsMsgKeySet.h"
|
||||
#include "nsINntpUrl.h"
|
||||
#include "nsIMsgFilterList.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
/* The below is all stuff that we remember for netlib about which
|
||||
articles we've already seen in the current newsgroup. */
|
||||
|
||||
typedef struct MSG_NewsKnown {
|
||||
nsMsgKeySet* set; /* Set of articles we've already gotten
|
||||
from the newsserver (if it's marked
|
||||
"read", then we've already gotten it).
|
||||
If an article is marked "read", it
|
||||
doesn't mean we're actually displaying
|
||||
it; it may be an article that no longer
|
||||
exists, or it may be one that we've
|
||||
marked read and we're only viewing
|
||||
unread messages. */
|
||||
|
||||
int32_t first_possible; /* The oldest article in this group. */
|
||||
int32_t last_possible; /* The newest article in this group. */
|
||||
|
||||
bool shouldGetOldest;
|
||||
} MSG_NewsKnown;
|
||||
|
||||
// This class should ultimately be part of a news group listing
|
||||
// state machine - either by inheritance or delegation.
|
||||
// Currently, a folder pane owns one and libnet news group listing
|
||||
// related messages get passed to this object.
|
||||
class nsNNTPNewsgroupList : public nsINNTPNewsgroupList, public nsIMsgFilterHitNotify
|
||||
#ifdef HAVE_CHANGELISTENER
|
||||
/* ,public ChangeListener */
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
nsNNTPNewsgroupList();
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINNTPNEWSGROUPLIST
|
||||
NS_DECL_NSIMSGFILTERHITNOTIFY
|
||||
|
||||
private:
|
||||
virtual ~nsNNTPNewsgroupList();
|
||||
|
||||
NS_METHOD CleanUp();
|
||||
|
||||
bool m_finishingXover;
|
||||
|
||||
#ifdef HAVE_CHANGELISTENER
|
||||
virtual void OnAnnouncerGoingAway (ChangeAnnouncer *instigator);
|
||||
#endif
|
||||
nsresult ParseLine(char *line, uint32_t *message_number);
|
||||
nsresult GetDatabase(const char *uri, nsIMsgDatabase **db);
|
||||
void SetProgressBarPercent(int32_t percent);
|
||||
void SetProgressStatus(const char16_t *aMessage);
|
||||
|
||||
void UpdateStatus(bool filtering, int32_t numDled, int32_t totToDL);
|
||||
|
||||
nsresult AddHeader(const char * header, const char * value);
|
||||
protected:
|
||||
bool m_getOldMessages;
|
||||
bool m_promptedAlready;
|
||||
bool m_downloadAll;
|
||||
int32_t m_maxArticles;
|
||||
int32_t m_lastPercent;
|
||||
PRTime m_lastStatusUpdate;
|
||||
|
||||
nsCOMPtr <nsIMsgNewsFolder> m_newsFolder;
|
||||
nsCOMPtr <nsIMsgDatabase> m_newsDB;
|
||||
nsCOMPtr <nsINntpUrl> m_runningURL;
|
||||
|
||||
/**
|
||||
* The last message that we have processed (XOVER or HEAD).
|
||||
*/
|
||||
nsMsgKey m_lastProcessedNumber;
|
||||
/**
|
||||
* The endpoints of the message chunk we are actually downloading.
|
||||
*/
|
||||
nsMsgKey m_firstMsgNumber, m_lastMsgNumber;
|
||||
/**
|
||||
* The endpoints of the message chunk we are capable of downloading.
|
||||
*/
|
||||
int32_t m_firstMsgToDownload, m_lastMsgToDownload;
|
||||
|
||||
struct MSG_NewsKnown m_knownArts;
|
||||
nsMsgKeySet *m_set;
|
||||
|
||||
nsTArray<nsCString> m_filterHeaders;
|
||||
uint32_t m_currentXHDRIndex;
|
||||
nsCString m_lastHeader;
|
||||
nsCString m_thisLine;
|
||||
|
||||
private:
|
||||
nsCOMPtr <nsIMsgWindow> m_msgWindow;
|
||||
nsCOMPtr <nsIMsgFilterList> m_filterList;
|
||||
nsCOMPtr <nsIMsgFilterList> m_serverFilterList;
|
||||
nsCOMPtr <nsIMsgDBHdr> m_newMsgHdr; // current message header we're building
|
||||
nsCOMArray<nsIMsgDBHdr> m_newHeaders;
|
||||
|
||||
bool m_addHdrToDB;
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsNNTPNewsgroupListState_h___ */
|
||||
|
||||
94
mailnews/news/src/nsNNTPNewsgroupPost.cpp
Normal file
94
mailnews/news/src/nsNNTPNewsgroupPost.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h" // precompiled header...
|
||||
#include "nsNNTPNewsgroupPost.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNNTPNewsgroupPost, nsINNTPNewsgroupPost)
|
||||
|
||||
nsNNTPNewsgroupPost::nsNNTPNewsgroupPost()
|
||||
{
|
||||
m_isControl=false;
|
||||
}
|
||||
|
||||
nsNNTPNewsgroupPost::~nsNNTPNewsgroupPost()
|
||||
{
|
||||
}
|
||||
|
||||
#define IMPL_GETSET(attribute, member) \
|
||||
NS_IMETHODIMP nsNNTPNewsgroupPost::Get##attribute(char **result) \
|
||||
{ \
|
||||
NS_ENSURE_ARG_POINTER(result); \
|
||||
*result = ToNewCString(member); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHODIMP nsNNTPNewsgroupPost::Set##attribute(const char *aValue) \
|
||||
{ \
|
||||
member.Assign(aValue); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
IMPL_GETSET(RelayVersion, m_header[IDX_HEADER_RELAYVERSION])
|
||||
IMPL_GETSET(PostingVersion, m_header[IDX_HEADER_POSTINGVERSION])
|
||||
IMPL_GETSET(From, m_header[IDX_HEADER_FROM])
|
||||
IMPL_GETSET(Date, m_header[IDX_HEADER_DATE])
|
||||
IMPL_GETSET(Subject, m_header[IDX_HEADER_SUBJECT])
|
||||
IMPL_GETSET(Path, m_header[IDX_HEADER_PATH])
|
||||
IMPL_GETSET(ReplyTo, m_header[IDX_HEADER_REPLYTO])
|
||||
IMPL_GETSET(Sender, m_header[IDX_HEADER_SENDER])
|
||||
IMPL_GETSET(FollowupTo, m_header[IDX_HEADER_FOLLOWUPTO])
|
||||
IMPL_GETSET(DateReceived, m_header[IDX_HEADER_DATERECEIVED])
|
||||
IMPL_GETSET(Expires, m_header[IDX_HEADER_EXPIRES])
|
||||
IMPL_GETSET(Control, m_header[IDX_HEADER_CONTROL])
|
||||
IMPL_GETSET(Distribution, m_header[IDX_HEADER_DISTRIBUTION])
|
||||
IMPL_GETSET(Organization, m_header[IDX_HEADER_ORGANIZATION])
|
||||
IMPL_GETSET(Body, m_body)
|
||||
|
||||
NS_IMETHODIMP nsNNTPNewsgroupPost::GetNewsgroups(char **result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = ToNewCString(m_header[IDX_HEADER_NEWSGROUPS]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNNTPNewsgroupPost::GetReferences(char **result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = ToNewCString(m_header[IDX_HEADER_REFERENCES]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNNTPNewsgroupPost::GetIsControl(bool *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = m_isControl;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNNTPNewsgroupPost::AddNewsgroup(const char *newsgroup)
|
||||
{
|
||||
m_header[IDX_HEADER_NEWSGROUPS].AppendLiteral(", ");
|
||||
m_header[IDX_HEADER_NEWSGROUPS].Append(newsgroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// the message can be stored in a file....allow accessors for getting and setting
|
||||
// the file name to post...
|
||||
nsresult
|
||||
nsNNTPNewsgroupPost::SetPostMessageFile(nsIFile * aPostMessageFile)
|
||||
{
|
||||
m_postMessageFile = aPostMessageFile;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNNTPNewsgroupPost::GetPostMessageFile(nsIFile ** aPostMessageFile)
|
||||
{
|
||||
if (aPostMessageFile)
|
||||
NS_IF_ADDREF(*aPostMessageFile = m_postMessageFile);
|
||||
return NS_OK;
|
||||
}
|
||||
61
mailnews/news/src/nsNNTPNewsgroupPost.h
Normal file
61
mailnews/news/src/nsNNTPNewsgroupPost.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsNNTPNewsgroupPost_h
|
||||
#define __nsNNTPNewsgroupPost_h
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsINNTPNewsgroupPost.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
#define IDX_HEADER_FROM 0
|
||||
#define IDX_HEADER_NEWSGROUPS 1
|
||||
#define IDX_HEADER_SUBJECT 2
|
||||
|
||||
// set this to the last required header
|
||||
#define IDX_HEADER_LAST_REQUIRED IDX_HEADER_SUBJECT
|
||||
|
||||
#define IDX_HEADER_PATH 3
|
||||
#define IDX_HEADER_DATE 4
|
||||
|
||||
#define IDX_HEADER_REPLYTO 5
|
||||
#define IDX_HEADER_SENDER 6
|
||||
#define IDX_HEADER_FOLLOWUPTO 7
|
||||
#define IDX_HEADER_DATERECEIVED 8
|
||||
#define IDX_HEADER_EXPIRES 9
|
||||
#define IDX_HEADER_CONTROL 10
|
||||
#define IDX_HEADER_DISTRIBUTION 11
|
||||
#define IDX_HEADER_ORGANIZATION 12
|
||||
#define IDX_HEADER_REFERENCES 13
|
||||
|
||||
// stuff that's required to be in the message,
|
||||
// but probably generated on the server
|
||||
#define IDX_HEADER_RELAYVERSION 14
|
||||
#define IDX_HEADER_POSTINGVERSION 15
|
||||
#define IDX_HEADER_MESSAGEID 16
|
||||
|
||||
// keep this in sync with the above
|
||||
#define HEADER_LAST IDX_HEADER_MESSAGEID
|
||||
|
||||
class nsNNTPNewsgroupPost : public nsINNTPNewsgroupPost {
|
||||
|
||||
public:
|
||||
nsNNTPNewsgroupPost();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINNTPNEWSGROUPPOST
|
||||
|
||||
private:
|
||||
virtual ~nsNNTPNewsgroupPost();
|
||||
|
||||
nsCOMPtr<nsIFile> m_postMessageFile;
|
||||
nsCString m_header[HEADER_LAST+1];
|
||||
nsCString m_body;
|
||||
bool m_isControl;
|
||||
};
|
||||
|
||||
#endif /* __nsNNTPNewsgroupPost_h */
|
||||
4777
mailnews/news/src/nsNNTPProtocol.cpp
Normal file
4777
mailnews/news/src/nsNNTPProtocol.cpp
Normal file
File diff suppressed because it is too large
Load diff
510
mailnews/news/src/nsNNTPProtocol.h
Normal file
510
mailnews/news/src/nsNNTPProtocol.h
Normal file
|
|
@ -0,0 +1,510 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNNTPProtocol_h___
|
||||
#define nsNNTPProtocol_h___
|
||||
|
||||
#include "nsMsgProtocol.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsIAsyncOutputStream.h"
|
||||
#include "nsINntpUrl.h"
|
||||
#include "nsINntpIncomingServer.h"
|
||||
#include "nsINNTPProtocol.h"
|
||||
|
||||
#include "nsINNTPNewsgroupList.h"
|
||||
#include "nsINNTPArticleList.h"
|
||||
#include "nsIMsgAsyncPrompter.h"
|
||||
#include "nsIMsgNewsFolder.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
|
||||
#include "nsMsgLineBuffer.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsICacheEntryOpenCallback.h"
|
||||
|
||||
// this is only needed as long as our libmime hack is in place
|
||||
#include "prio.h"
|
||||
|
||||
// State Flags (Note, I use the word state in terms of storing
|
||||
// state information about the connection (authentication, have we sent
|
||||
// commands, etc. I do not intend it to refer to protocol state)
|
||||
|
||||
#define NNTP_PAUSE_FOR_READ 0x00000001 /* should we pause for the next read */
|
||||
#define NNTP_PROXY_AUTH_REQUIRED 0x00000002 /* is auth required */
|
||||
#define NNTP_SENT_PROXY_AUTH 0x00000004 /* have we sent a proxy auth? */
|
||||
#define NNTP_READER_PERFORMED 0x00000010 /* have we sent any cmds to the server yet? */
|
||||
#define NNTP_USE_FANCY_NEWSGROUP 0x00000020 /* use LIST XACTIVE or LIST */
|
||||
#define NNTP_DESTROY_PROGRESS_GRAPH 0x00000040 /* do we need to destroy graph progress */
|
||||
#define NNTP_SOME_PROTOCOL_SUCCEEDED 0x0000080 /* some protocol has suceeded so don't kill the connection */
|
||||
#define NNTP_NO_XOVER_SUPPORT 0x00000100 /* xover command is not supported here */
|
||||
|
||||
/* states of the machine
|
||||
*/
|
||||
typedef enum _StatesEnum {
|
||||
NNTP_RESPONSE,
|
||||
#ifdef BLOCK_UNTIL_AVAILABLE_CONNECTION
|
||||
NNTP_BLOCK_UNTIL_CONNECTIONS_ARE_AVAILABLE,
|
||||
NNTP_CONNECTIONS_ARE_AVAILABLE,
|
||||
#endif
|
||||
NNTP_CONNECT,
|
||||
NNTP_CONNECT_WAIT,
|
||||
NNTP_LOGIN_RESPONSE,
|
||||
NNTP_SEND_MODE_READER,
|
||||
NNTP_SEND_MODE_READER_RESPONSE,
|
||||
SEND_LIST_EXTENSIONS,
|
||||
SEND_LIST_EXTENSIONS_RESPONSE,
|
||||
SEND_LIST_SEARCHES,
|
||||
SEND_LIST_SEARCHES_RESPONSE,
|
||||
NNTP_LIST_SEARCH_HEADERS,
|
||||
NNTP_LIST_SEARCH_HEADERS_RESPONSE,
|
||||
NNTP_GET_PROPERTIES,
|
||||
NNTP_GET_PROPERTIES_RESPONSE,
|
||||
SEND_LIST_SUBSCRIPTIONS,
|
||||
SEND_LIST_SUBSCRIPTIONS_RESPONSE,
|
||||
SEND_FIRST_NNTP_COMMAND,
|
||||
SEND_FIRST_NNTP_COMMAND_RESPONSE,
|
||||
SETUP_NEWS_STREAM,
|
||||
NNTP_BEGIN_AUTHORIZE,
|
||||
NNTP_AUTHORIZE_RESPONSE,
|
||||
NNTP_PASSWORD_RESPONSE,
|
||||
NNTP_READ_LIST_BEGIN,
|
||||
NNTP_READ_LIST,
|
||||
DISPLAY_NEWSGROUPS,
|
||||
NNTP_NEWGROUPS_BEGIN,
|
||||
NNTP_NEWGROUPS,
|
||||
NNTP_BEGIN_ARTICLE,
|
||||
NNTP_READ_ARTICLE,
|
||||
NNTP_XOVER_BEGIN,
|
||||
NNTP_FIGURE_NEXT_CHUNK,
|
||||
NNTP_XOVER_SEND,
|
||||
NNTP_XOVER_RESPONSE,
|
||||
NNTP_XOVER,
|
||||
NEWS_PROCESS_XOVER,
|
||||
NNTP_XHDR_SEND,
|
||||
NNTP_XHDR_RESPONSE,
|
||||
NNTP_READ_GROUP,
|
||||
NNTP_READ_GROUP_RESPONSE,
|
||||
NNTP_READ_GROUP_BODY,
|
||||
NNTP_SEND_GROUP_FOR_ARTICLE,
|
||||
NNTP_SEND_GROUP_FOR_ARTICLE_RESPONSE,
|
||||
NNTP_SEND_ARTICLE_NUMBER,
|
||||
NEWS_PROCESS_BODIES,
|
||||
NNTP_PRINT_ARTICLE_HEADERS,
|
||||
NNTP_SEND_POST_DATA,
|
||||
NNTP_SEND_POST_DATA_RESPONSE,
|
||||
NNTP_CHECK_FOR_MESSAGE,
|
||||
NEWS_START_CANCEL,
|
||||
NEWS_DO_CANCEL,
|
||||
NNTP_XPAT_SEND,
|
||||
NNTP_XPAT_RESPONSE,
|
||||
NNTP_SEARCH,
|
||||
NNTP_SEARCH_RESPONSE,
|
||||
NNTP_SEARCH_RESULTS,
|
||||
NNTP_LIST_PRETTY_NAMES,
|
||||
NNTP_LIST_PRETTY_NAMES_RESPONSE,
|
||||
NNTP_LIST_XACTIVE,
|
||||
NNTP_LIST_XACTIVE_RESPONSE,
|
||||
NNTP_LIST_GROUP,
|
||||
NNTP_LIST_GROUP_RESPONSE,
|
||||
NEWS_DONE,
|
||||
NEWS_POST_DONE,
|
||||
NEWS_ERROR,
|
||||
NNTP_ERROR,
|
||||
NEWS_FREE,
|
||||
NNTP_SUSPENDED
|
||||
} StatesEnum;
|
||||
|
||||
class nsICacheEntry;
|
||||
|
||||
class nsNNTPProtocol : public nsMsgProtocol,
|
||||
public nsINNTPProtocol,
|
||||
public nsITimerCallback,
|
||||
public nsICacheEntryOpenCallback,
|
||||
public nsIMsgAsyncPromptListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINNTPPROTOCOL
|
||||
NS_DECL_NSICACHEENTRYOPENCALLBACK
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
NS_DECL_NSIMSGASYNCPROMPTLISTENER
|
||||
|
||||
// Creating a protocol instance requires the URL
|
||||
// need to call Initialize after we do a new of nsNNTPProtocol
|
||||
nsNNTPProtocol(nsINntpIncomingServer *aServer, nsIURI *aURL,
|
||||
nsIMsgWindow *aMsgWindow);
|
||||
|
||||
// stop binding is a "notification" informing us that the stream associated with aURL is going away.
|
||||
NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports * aCtxt, nsresult aStatus) override;
|
||||
|
||||
char * m_ProxyServer; /* proxy server hostname */
|
||||
|
||||
NS_IMETHOD Cancel(nsresult status) override; // handle stop button
|
||||
NS_IMETHOD GetContentType(nsACString &aContentType) override;
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) override;
|
||||
NS_IMETHOD AsyncOpen2(nsIStreamListener *listener) override;
|
||||
NS_IMETHOD GetOriginalURI(nsIURI* *aURI) override;
|
||||
NS_IMETHOD SetOriginalURI(nsIURI* aURI) override;
|
||||
|
||||
nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer) override;
|
||||
|
||||
private:
|
||||
virtual ~nsNNTPProtocol();
|
||||
/**
|
||||
* Triggers the protocol state machine.
|
||||
* Most of the time, this machine will read as much input as it can before
|
||||
* closing.
|
||||
*
|
||||
* This method additionally handles some states not covered by other methods:
|
||||
* NEWS_DONE: Alias for NEWS_FREE
|
||||
* NEWS_POST_DONE: Alias for NEWS_FREE that cleans up the URL state
|
||||
* NEWS_ERROR: An error which permits further use of the connection
|
||||
* NNTP_ERROR: An error which does not permit further use of the connection
|
||||
* NEWS_FREE: Cleans up from the current URL and prepares for the next one
|
||||
* NNTP_SUSPENDED: A state where the state machine does not read input until
|
||||
* reenabled by a non-network related callback
|
||||
*
|
||||
* @note Use of NNTP_SUSPENDED is dangerous: if input comes along the socket,
|
||||
* the code will not read the input stream at all. Therefore, it is strongly
|
||||
* advised to suspend the request before using this state.
|
||||
*/
|
||||
virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
|
||||
uint64_t sourceOffset, uint32_t length) override;
|
||||
virtual nsresult CloseSocket() override;
|
||||
|
||||
// we have our own implementation of SendData which writes to the nntp log
|
||||
// and then calls the base class to transmit the data
|
||||
nsresult SendData(const char * dataBuffer, bool aSuppressLogging = false) override;
|
||||
|
||||
nsresult CleanupAfterRunningUrl();
|
||||
void Cleanup(); //free char* member variables
|
||||
|
||||
void ParseHeaderForCancel(char *buf);
|
||||
|
||||
virtual const char* GetType() override { return "nntp"; }
|
||||
|
||||
static void CheckIfAuthor(nsIMsgIdentity *aIdentity, const nsCString &aOldFrom, nsCString &aFrom);
|
||||
|
||||
nsCOMPtr <nsINNTPNewsgroupList> m_newsgroupList;
|
||||
nsCOMPtr <nsINNTPArticleList> m_articleList;
|
||||
|
||||
nsCOMPtr <nsIMsgNewsFolder> m_newsFolder;
|
||||
nsCOMPtr <nsIMsgWindow> m_msgWindow;
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStream> mDisplayInputStream;
|
||||
nsCOMPtr<nsIAsyncOutputStream> mDisplayOutputStream;
|
||||
nsMsgLineStreamBuffer * m_lineStreamBuffer; // used to efficiently extract lines from the incoming data stream
|
||||
// the nsINntpURL that is currently running
|
||||
nsCOMPtr<nsINntpUrl> m_runningURL;
|
||||
bool m_connectionBusy;
|
||||
bool m_fromCache; // is this connection from the cache?
|
||||
PRTime m_lastActiveTimeStamp;
|
||||
nsNewsAction m_newsAction;
|
||||
|
||||
// Generic state information -- What state are we in? What state do we want to go to
|
||||
// after the next response? What was the last response code? etc.
|
||||
StatesEnum m_nextState;
|
||||
StatesEnum m_nextStateAfterResponse;
|
||||
int32_t m_typeWanted; /* Article, List, or Group */
|
||||
int32_t m_responseCode; /* code returned from NNTP server */
|
||||
int32_t m_previousResponseCode;
|
||||
char *m_responseText; /* text returned from NNTP server */
|
||||
|
||||
char *m_dataBuf;
|
||||
uint32_t m_dataBufSize;
|
||||
|
||||
/* for group command */
|
||||
nsCString m_currentGroup; /* current group */
|
||||
|
||||
int32_t m_firstArticle;
|
||||
int32_t m_lastArticle;
|
||||
int32_t m_firstPossibleArticle;
|
||||
int32_t m_lastPossibleArticle;
|
||||
|
||||
int32_t m_numArticlesLoaded; /* How many articles we got XOVER lines for. */
|
||||
int32_t m_numArticlesWanted; /* How many articles we wanted to get XOVER lines for. */
|
||||
int32_t m_maxArticles; /* max articles to get during an XOVER */
|
||||
|
||||
// Cancelation specific state. In particular, the headers that should be
|
||||
// used for the cancelation message.
|
||||
// mscott: we can probably replace this stuff with nsString
|
||||
char *m_cancelFromHdr;
|
||||
char *m_cancelNewsgroups;
|
||||
char *m_cancelDistribution;
|
||||
char *m_cancelID;
|
||||
int32_t m_cancelStatus;
|
||||
|
||||
// variable for ReadNewsList
|
||||
int32_t m_readNewsListCount;
|
||||
|
||||
// Per news article state information. (article number, author, subject, id, etc
|
||||
nsCString m_messageID;
|
||||
int32_t m_articleNumber; /* current article number */
|
||||
nsCString m_searchData;
|
||||
|
||||
int32_t m_originalContentLength; /* the content length at the time of calling graph progress */
|
||||
|
||||
nsCOMPtr<nsIStringBundle> m_stringBundle;
|
||||
|
||||
nsCOMPtr<nsINntpIncomingServer> m_nntpServer;
|
||||
|
||||
nsresult GetNewsStringByName(const char *aName, char16_t **aString);
|
||||
nsresult GetNewsStringByID(int32_t stringID, char16_t **aString);
|
||||
|
||||
nsresult PostMessageInFile(nsIFile * filePath);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Communication methods --> Reading and writing protocol
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int32_t ReadLine(nsIInputStream * inputStream, uint32_t length, char ** line);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Protocol Methods --> This protocol is state driven so each protocol method
|
||||
// is designed to re-act to the current "state". I've attempted to
|
||||
// group them together based on functionality.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// gets the response code from the nntp server and the response line. Returns the TCP return code
|
||||
// from the read.
|
||||
nsresult NewsResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
// Interpret the server response after the connect.
|
||||
// Returns negative if the server responds unexpectedly
|
||||
nsresult LoginResponse();
|
||||
nsresult SendModeReader();
|
||||
nsresult SendModeReaderResponse();
|
||||
|
||||
nsresult SendListExtensions();
|
||||
nsresult SendListExtensionsResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
nsresult SendListSearches();
|
||||
nsresult SendListSearchesResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
nsresult SendListSearchHeaders();
|
||||
nsresult SendListSearchHeadersResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
nsresult GetProperties();
|
||||
nsresult GetPropertiesResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
nsresult SendListSubscriptions();
|
||||
nsresult SendListSubscriptionsResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
// Figure out what the first command is and send it.
|
||||
// Returns the status from the NETWrite.
|
||||
nsresult SendFirstNNTPCommand(nsIURI *url);
|
||||
|
||||
// Interprets the server response from the first command sent.
|
||||
// returns negative if the server responds unexpectedly.
|
||||
nsresult SendFirstNNTPCommandResponse();
|
||||
|
||||
nsresult SetupForTransfer();
|
||||
|
||||
nsresult SendGroupForArticle();
|
||||
nsresult SendGroupForArticleResponse();
|
||||
|
||||
nsresult SendArticleNumber();
|
||||
nsresult BeginArticle();
|
||||
nsresult ReadArticle(nsIInputStream *inputStream, uint32_t length);
|
||||
nsresult DisplayArticle(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// News authentication code
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Sends the username via AUTHINFO USER, NNTP_BEGIN_AUTHORIZE.
|
||||
* This also handles the step of getting authentication credentials; if this
|
||||
* requires a prompt to run, the connection will be suspended and we will
|
||||
* come back to this point.
|
||||
* Followed by: NNTP_AUTHORIZE_RESPONSE if the username was sent
|
||||
* NNTP_SUSPENDED if we need to wait for the password
|
||||
*/
|
||||
nsresult BeginAuthorization();
|
||||
/**
|
||||
* Sends the password if necessary, the state NNTP_AUTHORIZE_RESPONSE.
|
||||
* This also reads the result of the username.
|
||||
* Followed by: NNTP_PASSWORD_RESPONSE if a password is sent
|
||||
* NNTP_SEND_MODE_READER if MODE READER needed auth
|
||||
* SEND_FIRST_NNTP_COMMAND if any other command needed auth
|
||||
* NNTP_ERROR if the username was rejected
|
||||
*/
|
||||
nsresult AuthorizationResponse();
|
||||
/**
|
||||
* This state, NNTP_PASSWORD_RESPONSE, reads the password.
|
||||
* Followed by: NNTP_SEND_MODE_READER if MODE READER needed auth
|
||||
* SEND_FIRST_NNTP_COMMAND if any other command needed auth
|
||||
* NNTP_ERROR if the password was rejected
|
||||
*/
|
||||
nsresult PasswordResponse();
|
||||
|
||||
nsresult BeginReadNewsList();
|
||||
nsresult ReadNewsList(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
// Newsgroup specific protocol handlers
|
||||
nsresult DisplayNewsgroups();
|
||||
nsresult BeginNewsgroups();
|
||||
nsresult ProcessNewsgroups(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
// Protocol handlers used for posting data
|
||||
nsresult PostData();
|
||||
nsresult PostDataResponse();
|
||||
|
||||
nsresult CheckForArticle();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// XHDR, XOVER, HEAD filtering process handlers
|
||||
// These are ordered by the rough order of usage
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The first step in the filtering process, the state NNTP_XOVER_BEGIN.
|
||||
* This method sets up m_newsgroupList.
|
||||
* Followed by: NNTP_FIGURE_NEXT_CHUNK
|
||||
*/
|
||||
nsresult BeginReadXover();
|
||||
/**
|
||||
* The loop control for filtering, the state NNTP_FIGURE_NEXT_CHUNK.
|
||||
* This method contacts the newsgroupList to figure out which articles to
|
||||
* download and then prepares it for XOVER support.
|
||||
* Followed by: NEWS_PROCESS_XOVER if everything is finished
|
||||
* NNTP_READ_GROUP if XOVER doesn't work
|
||||
* NNTP_XOVER_SEND if XOVER does work
|
||||
*/
|
||||
nsresult FigureNextChunk();
|
||||
|
||||
// The XOVER process core
|
||||
/**
|
||||
* The state NNTP_XOVER_SEND, which actually sends the message.
|
||||
* Followed by: NNTP_XOVER_RESPONSE
|
||||
*/
|
||||
nsresult XoverSend();
|
||||
/**
|
||||
* This state, NNTP_XOVER_RESPONSE, actually checks the XOVER capabiliity.
|
||||
* Followed by: NNTP_XOVER if XOVER is supported
|
||||
* NNTP_READ_GROUP if it isn't
|
||||
*/
|
||||
nsresult ReadXoverResponse();
|
||||
/**
|
||||
* This state, NNTP_XOVER, processes the results from the XOVER command.
|
||||
* It asks nsNNTPNewsgroupList to process the line using ProcessXOVERLINE.
|
||||
* Followed by: NNTP_XHDR_SEND
|
||||
*/
|
||||
nsresult ReadXover(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
// The XHDR process core
|
||||
/**
|
||||
* This state, NNTP_XHDR_SEND, sends the XHDR command.
|
||||
* The headers are all managed by nsNNTPNewsgroupList, and this picks them up
|
||||
* one by one as they are needed.
|
||||
* Followed by: NNTP_XHDR_RESPONSE if there is a header to be sent
|
||||
* NNTP_FIGURE_NEXT_CHUNK if all headers have been sent
|
||||
*/
|
||||
nsresult XhdrSend();
|
||||
/**
|
||||
* This state, NNTP_XHDR_RESPONSE, processes the XHDR response.
|
||||
* It mostly passes the information off to nsNNTPNewsgroupList, and only does
|
||||
* response code checking and a bit of preprocessing. Note that if XHDR
|
||||
* doesn't work properly, HEAD fallback is switched on and all subsequent
|
||||
* chunks will NOT use XOVER.
|
||||
* Followed by: NNTP_READ_GROUP if XHDR doesn't work properly
|
||||
* NNTP_XHDR_SEND when finished processing XHR.
|
||||
*/
|
||||
nsresult XhdrResponse(nsIInputStream *inputStream);
|
||||
|
||||
// HEAD processing core
|
||||
/**
|
||||
* This state, NNTP_READ_GROUP, is the control for the HEAD processor.
|
||||
* It sends the HEAD command and increments the article number until it is
|
||||
* finished. WARNING: HEAD is REALLY SLOW.
|
||||
* Followed by: NNTP_FIGURE_NEXT_CHUNK when it is finished
|
||||
* NNTP_READ_GROUP_RESPONSE when it is not
|
||||
*/
|
||||
nsresult ReadHeaders();
|
||||
/**
|
||||
* This state, NNTP_READ_GROUP_RESPONSE, checks if the article exists.
|
||||
* Because it is required by NNTP, if it doesn't work, the only problem would
|
||||
* be that the article doesn't exist. Passes off article number data to
|
||||
* nsNNTPNewsgroupList.
|
||||
* Followed by: NNTP_READ_GROUP_BODY if the article exists
|
||||
* NNTP_READ_GROUP if it doesn't.
|
||||
*/
|
||||
nsresult ReadNewsgroupResponse();
|
||||
/**
|
||||
* This state, NNTP_READ_GROUP_BODY, reads the body of the HEAD command.
|
||||
* Once again, it passes information off to nsNNTPNewsgroupList.
|
||||
* Followed by: NNTP_READ_GROUP
|
||||
*/
|
||||
nsresult ReadNewsgroupBody(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
/**
|
||||
* This state, NNTP_PROCESS_XOVER, is the final step of the filter-processing
|
||||
* code. Currently, all it does is cleans up the unread count and calls the
|
||||
* filters, both via nsNNTPNewsgroupList.
|
||||
* Followed by: NEWS_DONE
|
||||
*/
|
||||
nsresult ProcessXover();
|
||||
|
||||
|
||||
|
||||
// Canceling
|
||||
nsresult StartCancel();
|
||||
nsresult DoCancel();
|
||||
|
||||
// XPAT
|
||||
nsresult XPATSend();
|
||||
nsresult XPATResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
nsresult ListPrettyNames();
|
||||
nsresult ListPrettyNamesResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
nsresult ListXActive();
|
||||
nsresult ListXActiveResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
// for "?list-ids"
|
||||
nsresult SendListGroup();
|
||||
nsresult SendListGroupResponse(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
// Searching Protocol....
|
||||
nsresult Search();
|
||||
nsresult SearchResponse();
|
||||
nsresult SearchResults(nsIInputStream *inputStream, uint32_t length);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// End of Protocol Methods
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult ParseURL(nsIURI *aURL, nsCString &aGroup, nsCString &aMessageID);
|
||||
|
||||
void SetProgressBarPercent(uint32_t aProgress, uint32_t aProgressMax);
|
||||
nsresult SetProgressStatus(const char16_t *aMessage);
|
||||
nsresult InitializeNewsFolderFromUri(const char *uri);
|
||||
void TimerCallback();
|
||||
|
||||
void HandleAuthenticationFailure();
|
||||
nsCOMPtr <nsIInputStream> mInputStream;
|
||||
nsCOMPtr <nsITimer> mUpdateTimer;
|
||||
nsresult AlertError(int32_t errorCode, const char *text);
|
||||
int32_t mBytesReceived;
|
||||
int32_t mBytesReceivedSinceLastStatusUpdate;
|
||||
PRTime m_startTime;
|
||||
int32_t mNumGroupsListed;
|
||||
nsMsgKey m_key;
|
||||
|
||||
nsresult SetCurrentGroup(); /* sets m_currentGroup. should be called after doing a successful GROUP command */
|
||||
nsresult CleanupNewsgroupList(); /* cleans up m_newsgroupList, and set it to null */
|
||||
|
||||
// cache related helper methods
|
||||
void FinishMemCacheEntry(bool valid); // either mark it valid, or doom it
|
||||
nsresult OpenCacheEntry(); // makes a request to the cache service for a cache entry for a url
|
||||
bool ReadFromLocalCache(); // attempts to read the url out of our local (offline) cache....
|
||||
nsresult ReadFromNewsConnection(); // creates a new news connection to read the url
|
||||
nsresult ReadFromMemCache(nsICacheEntry *entry); // attempts to read the url out of our memory cache
|
||||
nsresult SetupPartExtractorListener(nsIStreamListener * aConsumer);
|
||||
};
|
||||
|
||||
|
||||
#endif // nsNNTPProtocol_h___
|
||||
141
mailnews/news/src/nsNewsAutoCompleteSearch.js
Normal file
141
mailnews/news/src/nsNewsAutoCompleteSearch.js
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cu = Components.utils;
|
||||
|
||||
Cu.import("resource:///modules/mailServices.js");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var kACR = Ci.nsIAutoCompleteResult;
|
||||
var kSupportedTypes = new Set(["addr_newsgroups", "addr_followup"]);
|
||||
|
||||
function nsNewsAutoCompleteResult(aSearchString) {
|
||||
// Can't create this in the prototype as we'd get the same array for
|
||||
// all instances
|
||||
this._searchResults = [];
|
||||
this.searchString = aSearchString;
|
||||
}
|
||||
|
||||
nsNewsAutoCompleteResult.prototype = {
|
||||
_searchResults: null,
|
||||
|
||||
// nsIAutoCompleteResult
|
||||
|
||||
searchString: null,
|
||||
searchResult: kACR.RESULT_NOMATCH,
|
||||
defaultIndex: -1,
|
||||
errorDescription: null,
|
||||
|
||||
get matchCount() {
|
||||
return this._searchResults.length;
|
||||
},
|
||||
|
||||
getValueAt: function getValueAt(aIndex) {
|
||||
return this._searchResults[aIndex].value;
|
||||
},
|
||||
|
||||
getLabelAt: function getLabelAt(aIndex) {
|
||||
return this._searchResults[aIndex].value;
|
||||
},
|
||||
|
||||
getCommentAt: function getCommentAt(aIndex) {
|
||||
return this._searchResults[aIndex].comment;
|
||||
},
|
||||
|
||||
getStyleAt: function getStyleAt(aIndex) {
|
||||
return "subscribed-news";
|
||||
},
|
||||
|
||||
getImageAt: function getImageAt(aIndex) {
|
||||
return "";
|
||||
},
|
||||
|
||||
getFinalCompleteValueAt: function(aIndex) {
|
||||
return this.getValueAt(aIndex);
|
||||
},
|
||||
|
||||
removeValueAt: function removeValueAt(aRowIndex, aRemoveFromDB) {
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([kACR])
|
||||
}
|
||||
|
||||
function nsNewsAutoCompleteSearch() {}
|
||||
|
||||
nsNewsAutoCompleteSearch.prototype = {
|
||||
// For component registration
|
||||
classDescription: "Newsgroup Autocomplete",
|
||||
classID: Components.ID("e9bb3330-ac7e-11de-8a39-0800200c9a66"),
|
||||
|
||||
cachedAccountKey: "",
|
||||
cachedServer: null,
|
||||
|
||||
/**
|
||||
* Find the newsgroup server associated with the given accountKey.
|
||||
*
|
||||
* @param accountKey The key of the account.
|
||||
* @return The incoming news server (or null if one does not exist).
|
||||
*/
|
||||
_findServer: function _findServer(accountKey) {
|
||||
let account = MailServices.accounts.getAccount(accountKey);
|
||||
|
||||
if (account.incomingServer.type == 'nntp')
|
||||
return account.incomingServer;
|
||||
else
|
||||
return null;
|
||||
},
|
||||
|
||||
// nsIAutoCompleteSearch
|
||||
startSearch: function startSearch(aSearchString, aSearchParam,
|
||||
aPreviousResult, aListener) {
|
||||
let params = aSearchParam ? JSON.parse(aSearchParam) : {};
|
||||
let result = new nsNewsAutoCompleteResult(aSearchString);
|
||||
if (!("type" in params) || !("accountKey" in params) ||
|
||||
!kSupportedTypes.has(params.type)) {
|
||||
result.searchResult = kACR.RESULT_IGNORED;
|
||||
aListener.onSearchResult(this, result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (("accountKey" in params) && (params.accountKey != this.cachedAccountKey)) {
|
||||
this.cachedAccountKey = params.accountKey;
|
||||
this.cachedServer = this._findServer(params.accountKey);
|
||||
}
|
||||
|
||||
if (this.cachedServer) {
|
||||
let groups = this.cachedServer.rootFolder.subFolders;
|
||||
while (groups.hasMoreElements()) {
|
||||
let curr = groups.getNext().QueryInterface(Ci.nsIMsgFolder);
|
||||
if (curr.prettiestName.includes(aSearchString)) {
|
||||
result._searchResults.push({
|
||||
value: curr.prettiestName,
|
||||
comment: this.cachedServer.prettyName
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.matchCount) {
|
||||
result.searchResult = kACR.RESULT_SUCCESS;
|
||||
// If the user does not select anything, use the first entry:
|
||||
result.defaultIndex = 0;
|
||||
}
|
||||
aListener.onSearchResult(this, result);
|
||||
},
|
||||
|
||||
stopSearch: function stopSearch() {
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteSearch])
|
||||
};
|
||||
|
||||
// Module
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([nsNewsAutoCompleteSearch]);
|
||||
2
mailnews/news/src/nsNewsAutoCompleteSearch.manifest
Normal file
2
mailnews/news/src/nsNewsAutoCompleteSearch.manifest
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
component {e9bb3330-ac7e-11de-8a39-0800200c9a66} nsNewsAutoCompleteSearch.js
|
||||
contract @mozilla.org/autocomplete/search;1?name=news {e9bb3330-ac7e-11de-8a39-0800200c9a66}
|
||||
91
mailnews/news/src/nsNewsDownloadDialogArgs.cpp
Normal file
91
mailnews/news/src/nsNewsDownloadDialogArgs.cpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNewsDownloadDialogArgs.h"
|
||||
|
||||
nsNewsDownloadDialogArgs::nsNewsDownloadDialogArgs()
|
||||
{
|
||||
mArticleCount = 0;
|
||||
mServerKey = "";
|
||||
mHitOK = false;
|
||||
mDownloadAll = false;
|
||||
}
|
||||
|
||||
nsNewsDownloadDialogArgs::~nsNewsDownloadDialogArgs()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNewsDownloadDialogArgs, nsINewsDownloadDialogArgs)
|
||||
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::GetGroupName(nsAString & aGroupName)
|
||||
{
|
||||
aGroupName = mGroupName;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::SetGroupName(const nsAString & aGroupName)
|
||||
{
|
||||
|
||||
mGroupName = aGroupName;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::GetArticleCount(int32_t *aArticleCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aArticleCount);
|
||||
|
||||
*aArticleCount = mArticleCount;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::SetArticleCount(int32_t aArticleCount)
|
||||
{
|
||||
mArticleCount = aArticleCount;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::GetServerKey(char * *aServerKey)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aServerKey);
|
||||
|
||||
*aServerKey = ToNewCString(mServerKey);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::SetServerKey(const char * aServerKey)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aServerKey);
|
||||
|
||||
mServerKey = aServerKey;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::GetHitOK(bool *aHitOK)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aHitOK);
|
||||
|
||||
*aHitOK = mHitOK;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::SetHitOK(bool aHitOK)
|
||||
{
|
||||
mHitOK = aHitOK;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::GetDownloadAll(bool *aDownloadAll)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDownloadAll);
|
||||
|
||||
*aDownloadAll = mDownloadAll;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloadDialogArgs::SetDownloadAll(bool aDownloadAll)
|
||||
{
|
||||
mDownloadAll = aDownloadAll;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
30
mailnews/news/src/nsNewsDownloadDialogArgs.h
Normal file
30
mailnews/news/src/nsNewsDownloadDialogArgs.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNewsDownloadDialogArgs_h__
|
||||
#define nsNewsDownloadDialogArgs_h__
|
||||
|
||||
#include "nsINewsDownloadDialogArgs.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
class nsNewsDownloadDialogArgs : public nsINewsDownloadDialogArgs
|
||||
{
|
||||
public:
|
||||
nsNewsDownloadDialogArgs();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSINEWSDOWNLOADDIALOGARGS
|
||||
|
||||
private:
|
||||
virtual ~nsNewsDownloadDialogArgs();
|
||||
|
||||
nsString mGroupName;
|
||||
int32_t mArticleCount;
|
||||
nsCString mServerKey;
|
||||
bool mHitOK;
|
||||
bool mDownloadAll;
|
||||
};
|
||||
|
||||
#endif // nsNewsDownloadDialogArgs_h__
|
||||
586
mailnews/news/src/nsNewsDownloader.cpp
Normal file
586
mailnews/news/src/nsNewsDownloader.cpp
Normal file
|
|
@ -0,0 +1,586 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nntpCore.h"
|
||||
#include "netCore.h"
|
||||
#include "nsIMsgNewsFolder.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsNewsDownloader.h"
|
||||
#include "nsINntpService.h"
|
||||
#include "nsMsgNewsCID.h"
|
||||
#include "nsIMsgSearchSession.h"
|
||||
#include "nsIMsgSearchTerm.h"
|
||||
#include "nsIMsgSearchValidityManager.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsIMsgAccountManager.h"
|
||||
#include "nsMsgFolderFlags.h"
|
||||
#include "nsIRequestObserver.h"
|
||||
#include "nsIMsgMailSession.h"
|
||||
#include "nsMsgMessageFlags.h"
|
||||
#include "nsIMsgStatusFeedback.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsArrayUtils.h"
|
||||
|
||||
// This file contains the news article download state machine.
|
||||
|
||||
// if pIds is not null, download the articles whose id's are passed in. Otherwise,
|
||||
// which articles to download is determined by nsNewsDownloader object,
|
||||
// or subclasses thereof. News can download marked objects, for example.
|
||||
nsresult nsNewsDownloader::DownloadArticles(nsIMsgWindow *window, nsIMsgFolder *folder, nsTArray<nsMsgKey> *pIds)
|
||||
{
|
||||
if (pIds != nullptr)
|
||||
m_keysToDownload.InsertElementsAt(0, pIds->Elements(), pIds->Length());
|
||||
|
||||
if (!m_keysToDownload.IsEmpty())
|
||||
m_downloadFromKeys = true;
|
||||
|
||||
m_folder = folder;
|
||||
m_window = window;
|
||||
m_numwrote = 0;
|
||||
|
||||
bool headersToDownload = GetNextHdrToRetrieve();
|
||||
// should we have a special error code for failure here?
|
||||
return (headersToDownload) ? DownloadNext(true) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* Saving news messages
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNewsDownloader, nsIUrlListener, nsIMsgSearchNotify)
|
||||
|
||||
nsNewsDownloader::nsNewsDownloader(nsIMsgWindow *window, nsIMsgDatabase *msgDB, nsIUrlListener *listener)
|
||||
{
|
||||
m_numwrote = 0;
|
||||
m_downloadFromKeys = false;
|
||||
m_newsDB = msgDB;
|
||||
m_abort = false;
|
||||
m_listener = listener;
|
||||
m_window = window;
|
||||
m_lastPercent = -1;
|
||||
m_lastProgressTime = 0;
|
||||
// not the perfect place for this, but I think it will work.
|
||||
if (m_window)
|
||||
m_window->SetStopped(false);
|
||||
}
|
||||
|
||||
nsNewsDownloader::~nsNewsDownloader()
|
||||
{
|
||||
if (m_listener)
|
||||
m_listener->OnStopRunningUrl(/* don't have a url */nullptr, m_status);
|
||||
if (m_newsDB)
|
||||
{
|
||||
m_newsDB->Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
m_newsDB = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNewsDownloader::OnStartRunningUrl(nsIURI* url)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNewsDownloader::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
|
||||
{
|
||||
bool stopped = false;
|
||||
if (m_window)
|
||||
m_window->GetStopped(&stopped);
|
||||
if (stopped)
|
||||
exitCode = NS_BINDING_ABORTED;
|
||||
|
||||
nsresult rv = exitCode;
|
||||
if (NS_SUCCEEDED(exitCode) || exitCode == NS_MSG_NEWS_ARTICLE_NOT_FOUND)
|
||||
rv = DownloadNext(false);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsNewsDownloader::DownloadNext(bool firstTimeP)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!firstTimeP)
|
||||
{
|
||||
bool moreHeaders = GetNextHdrToRetrieve();
|
||||
if (!moreHeaders)
|
||||
{
|
||||
if (m_listener)
|
||||
m_listener->OnStopRunningUrl(nullptr, NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
StartDownload();
|
||||
m_wroteAnyP = false;
|
||||
nsCOMPtr <nsINntpService> nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID,&rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return nntpService->FetchMessage(m_folder, m_keyToDownload, m_window, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
bool DownloadNewsArticlesToOfflineStore::GetNextHdrToRetrieve()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (m_downloadFromKeys)
|
||||
return nsNewsDownloader::GetNextHdrToRetrieve();
|
||||
|
||||
if (m_headerEnumerator == nullptr)
|
||||
rv = m_newsDB->EnumerateMessages(getter_AddRefs(m_headerEnumerator));
|
||||
|
||||
bool hasMore = false;
|
||||
|
||||
while (NS_SUCCEEDED(rv = m_headerEnumerator->HasMoreElements(&hasMore)) && hasMore)
|
||||
{
|
||||
nsCOMPtr <nsISupports> supports;
|
||||
rv = m_headerEnumerator->GetNext(getter_AddRefs(supports));
|
||||
m_newsHeader = do_QueryInterface(supports);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
uint32_t hdrFlags;
|
||||
m_newsHeader->GetFlags(&hdrFlags);
|
||||
if (hdrFlags & nsMsgMessageFlags::Marked)
|
||||
{
|
||||
m_newsHeader->GetMessageKey(&m_keyToDownload);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_newsHeader = nullptr;
|
||||
}
|
||||
}
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
void nsNewsDownloader::Abort() {}
|
||||
void nsNewsDownloader::Complete() {}
|
||||
|
||||
bool nsNewsDownloader::GetNextHdrToRetrieve()
|
||||
{
|
||||
nsresult rv;
|
||||
if (m_downloadFromKeys)
|
||||
{
|
||||
if (m_numwrote >= (int32_t) m_keysToDownload.Length())
|
||||
return false;
|
||||
|
||||
m_keyToDownload = m_keysToDownload[m_numwrote++];
|
||||
int32_t percent;
|
||||
percent = (100 * m_numwrote) / (int32_t) m_keysToDownload.Length();
|
||||
|
||||
int64_t nowMS = 0;
|
||||
if (percent < 100) // always need to do 100%
|
||||
{
|
||||
nowMS = PR_IntervalToMilliseconds(PR_IntervalNow());
|
||||
if (nowMS - m_lastProgressTime < 750)
|
||||
return true;
|
||||
}
|
||||
|
||||
m_lastProgressTime = nowMS;
|
||||
nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_folder);
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
NS_ENSURE_TRUE(bundleService, false);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsAutoString firstStr;
|
||||
firstStr.AppendInt(m_numwrote);
|
||||
nsAutoString totalStr;
|
||||
totalStr.AppendInt(int(m_keysToDownload.Length()));
|
||||
nsString prettiestName;
|
||||
nsString statusString;
|
||||
|
||||
m_folder->GetPrettiestName(prettiestName);
|
||||
|
||||
const char16_t *formatStrings[3] = { firstStr.get(), totalStr.get(), prettiestName.get() };
|
||||
rv = bundle->FormatStringFromName(u"downloadingArticlesForOffline",
|
||||
formatStrings, 3, getter_Copies(statusString));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
ShowProgress(statusString.get(), percent);
|
||||
return true;
|
||||
}
|
||||
NS_ASSERTION(false, "shouldn't get here if we're not downloading from keys.");
|
||||
return false; // shouldn't get here if we're not downloading from keys.
|
||||
}
|
||||
|
||||
nsresult nsNewsDownloader::ShowProgress(const char16_t *progressString, int32_t percent)
|
||||
{
|
||||
if (!m_statusFeedback)
|
||||
{
|
||||
if (m_window)
|
||||
m_window->GetStatusFeedback(getter_AddRefs(m_statusFeedback));
|
||||
}
|
||||
if (m_statusFeedback)
|
||||
{
|
||||
m_statusFeedback->ShowStatusString(nsDependentString(progressString));
|
||||
if (percent != m_lastPercent)
|
||||
{
|
||||
m_statusFeedback->ShowProgress(percent);
|
||||
m_lastPercent = percent;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DownloadNewsArticlesToOfflineStore::OnStartRunningUrl(nsIURI* url)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP DownloadNewsArticlesToOfflineStore::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
|
||||
{
|
||||
m_status = exitCode;
|
||||
if (m_newsHeader != nullptr)
|
||||
{
|
||||
#ifdef DEBUG_bienvenu
|
||||
// XP_Trace("finished retrieving %ld\n", m_newsHeader->GetMessageKey());
|
||||
#endif
|
||||
if (m_newsDB)
|
||||
{
|
||||
nsMsgKey msgKey;
|
||||
m_newsHeader->GetMessageKey(&msgKey);
|
||||
m_newsDB->MarkMarked(msgKey, false, nullptr);
|
||||
}
|
||||
}
|
||||
m_newsHeader = nullptr;
|
||||
return nsNewsDownloader::OnStopRunningUrl(url, exitCode);
|
||||
}
|
||||
|
||||
int DownloadNewsArticlesToOfflineStore::FinishDownload()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsNewsDownloader::OnSearchHit(nsIMsgDBHdr *header, nsIMsgFolder *folder)
|
||||
{
|
||||
NS_ENSURE_ARG(header);
|
||||
|
||||
|
||||
uint32_t msgFlags;
|
||||
header->GetFlags(&msgFlags);
|
||||
// only need to download articles we don't already have...
|
||||
if (! (msgFlags & nsMsgMessageFlags::Offline))
|
||||
{
|
||||
nsMsgKey key;
|
||||
header->GetMessageKey(&key);
|
||||
m_keysToDownload.AppendElement(key);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNewsDownloader::OnSearchDone(nsresult status)
|
||||
{
|
||||
if (m_keysToDownload.IsEmpty())
|
||||
{
|
||||
if (m_listener)
|
||||
return m_listener->OnStopRunningUrl(nullptr, NS_OK);
|
||||
}
|
||||
nsresult rv = DownloadArticles(m_window, m_folder,
|
||||
/* we've already set m_keysToDownload, so don't pass it in */ nullptr);
|
||||
if (NS_FAILED(rv))
|
||||
if (m_listener)
|
||||
m_listener->OnStopRunningUrl(nullptr, rv);
|
||||
|
||||
return rv;
|
||||
}
|
||||
NS_IMETHODIMP nsNewsDownloader::OnNewSearch()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int DownloadNewsArticlesToOfflineStore::StartDownload()
|
||||
{
|
||||
m_newsDB->GetMsgHdrForKey(m_keyToDownload, getter_AddRefs(m_newsHeader));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DownloadNewsArticlesToOfflineStore::DownloadNewsArticlesToOfflineStore(nsIMsgWindow *window, nsIMsgDatabase *db, nsIUrlListener *listener)
|
||||
: nsNewsDownloader(window, db, listener)
|
||||
{
|
||||
m_newsDB = db;
|
||||
}
|
||||
|
||||
DownloadNewsArticlesToOfflineStore::~DownloadNewsArticlesToOfflineStore()
|
||||
{
|
||||
}
|
||||
|
||||
DownloadMatchingNewsArticlesToNewsDB::DownloadMatchingNewsArticlesToNewsDB
|
||||
(nsIMsgWindow *window, nsIMsgFolder *folder, nsIMsgDatabase *newsDB,
|
||||
nsIUrlListener *listener) :
|
||||
DownloadNewsArticlesToOfflineStore(window, newsDB, listener)
|
||||
{
|
||||
m_window = window;
|
||||
m_folder = folder;
|
||||
m_newsDB = newsDB;
|
||||
m_downloadFromKeys = true; // search term matching means downloadFromKeys.
|
||||
}
|
||||
|
||||
DownloadMatchingNewsArticlesToNewsDB::~DownloadMatchingNewsArticlesToNewsDB()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMsgDownloadAllNewsgroups, nsIUrlListener)
|
||||
|
||||
|
||||
nsMsgDownloadAllNewsgroups::nsMsgDownloadAllNewsgroups(nsIMsgWindow *window, nsIUrlListener *listener)
|
||||
{
|
||||
m_window = window;
|
||||
m_listener = listener;
|
||||
m_downloaderForGroup = new DownloadMatchingNewsArticlesToNewsDB(window, nullptr, nullptr, this);
|
||||
NS_IF_ADDREF(m_downloaderForGroup);
|
||||
m_downloadedHdrsForCurGroup = false;
|
||||
}
|
||||
|
||||
nsMsgDownloadAllNewsgroups::~nsMsgDownloadAllNewsgroups()
|
||||
{
|
||||
NS_IF_RELEASE(m_downloaderForGroup);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDownloadAllNewsgroups::OnStartRunningUrl(nsIURI* url)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgDownloadAllNewsgroups::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
|
||||
{
|
||||
nsresult rv = exitCode;
|
||||
if (NS_SUCCEEDED(exitCode) || exitCode == NS_MSG_NEWS_ARTICLE_NOT_FOUND)
|
||||
{
|
||||
if (m_downloadedHdrsForCurGroup)
|
||||
{
|
||||
bool savingArticlesOffline = false;
|
||||
nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_currentFolder);
|
||||
if (newsFolder)
|
||||
newsFolder->GetSaveArticleOffline(&savingArticlesOffline);
|
||||
|
||||
m_downloadedHdrsForCurGroup = false;
|
||||
if (savingArticlesOffline) // skip this group - we're saving to it already
|
||||
rv = ProcessNextGroup();
|
||||
else
|
||||
rv = DownloadMsgsForCurrentGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = ProcessNextGroup();
|
||||
}
|
||||
}
|
||||
else if (m_listener) // notify main observer.
|
||||
m_listener->OnStopRunningUrl(url, exitCode);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves m_currentServer at the next nntp "server" that
|
||||
* might have folders to download for offline use. If no more servers,
|
||||
* m_currentServer will be left at nullptr and the function returns false.
|
||||
* Also, sets up m_serverEnumerator to enumerate over the server.
|
||||
* If no servers found, m_serverEnumerator will be left at null.
|
||||
*/
|
||||
bool nsMsgDownloadAllNewsgroups::AdvanceToNextServer()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!m_allServers)
|
||||
{
|
||||
nsCOMPtr<nsIMsgAccountManager> accountManager =
|
||||
do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
|
||||
NS_ASSERTION(accountManager && NS_SUCCEEDED(rv), "couldn't get account mgr");
|
||||
if (!accountManager || NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
rv = accountManager->GetAllServers(getter_AddRefs(m_allServers));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
}
|
||||
uint32_t serverIndex = 0;
|
||||
if (m_currentServer)
|
||||
{
|
||||
rv = m_allServers->IndexOf(0, m_currentServer, &serverIndex);
|
||||
if (NS_FAILED(rv))
|
||||
serverIndex = -1;
|
||||
|
||||
++serverIndex;
|
||||
}
|
||||
m_currentServer = nullptr;
|
||||
uint32_t numServers;
|
||||
m_allServers->GetLength(&numServers);
|
||||
nsCOMPtr <nsIMsgFolder> rootFolder;
|
||||
|
||||
while (serverIndex < numServers)
|
||||
{
|
||||
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryElementAt(m_allServers, serverIndex);
|
||||
serverIndex++;
|
||||
|
||||
nsCOMPtr <nsINntpIncomingServer> newsServer = do_QueryInterface(server);
|
||||
if (!newsServer) // we're only looking for news servers
|
||||
continue;
|
||||
|
||||
if (server)
|
||||
{
|
||||
m_currentServer = server;
|
||||
server->GetRootFolder(getter_AddRefs(rootFolder));
|
||||
if (rootFolder)
|
||||
{
|
||||
rv = rootFolder->GetDescendants(getter_AddRefs(m_allFolders));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = m_allFolders->Enumerate(getter_AddRefs(m_serverEnumerator));
|
||||
if (NS_SUCCEEDED(rv) && m_serverEnumerator)
|
||||
{
|
||||
bool hasMore = false;
|
||||
rv = m_serverEnumerator->HasMoreElements(&hasMore);
|
||||
if (NS_SUCCEEDED(rv) && hasMore)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets m_currentFolder to the next usable folder.
|
||||
*
|
||||
* @return False if no more folders found, otherwise true.
|
||||
*/
|
||||
bool nsMsgDownloadAllNewsgroups::AdvanceToNextGroup()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (m_currentFolder)
|
||||
{
|
||||
nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_currentFolder);
|
||||
if (newsFolder)
|
||||
newsFolder->SetSaveArticleOffline(false);
|
||||
|
||||
nsCOMPtr<nsIMsgMailSession> session =
|
||||
do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && session)
|
||||
{
|
||||
bool folderOpen;
|
||||
uint32_t folderFlags;
|
||||
m_currentFolder->GetFlags(&folderFlags);
|
||||
session->IsFolderOpenInWindow(m_currentFolder, &folderOpen);
|
||||
if (!folderOpen && ! (folderFlags & (nsMsgFolderFlags::Trash | nsMsgFolderFlags::Inbox)))
|
||||
m_currentFolder->SetMsgDatabase(nullptr);
|
||||
}
|
||||
m_currentFolder = nullptr;
|
||||
}
|
||||
|
||||
bool hasMore = false;
|
||||
if (m_currentServer)
|
||||
m_serverEnumerator->HasMoreElements(&hasMore);
|
||||
if (!hasMore)
|
||||
hasMore = AdvanceToNextServer();
|
||||
|
||||
if (hasMore)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
rv = m_serverEnumerator->GetNext(getter_AddRefs(supports));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
m_currentFolder = do_QueryInterface(supports);
|
||||
}
|
||||
return m_currentFolder;
|
||||
}
|
||||
|
||||
nsresult DownloadMatchingNewsArticlesToNewsDB::RunSearch(nsIMsgFolder *folder, nsIMsgDatabase *newsDB, nsIMsgSearchSession *searchSession)
|
||||
{
|
||||
m_folder = folder;
|
||||
m_newsDB = newsDB;
|
||||
m_searchSession = searchSession;
|
||||
|
||||
m_keysToDownload.Clear();
|
||||
|
||||
NS_ENSURE_ARG(searchSession);
|
||||
NS_ENSURE_ARG(folder);
|
||||
|
||||
searchSession->RegisterListener(this,
|
||||
nsIMsgSearchSession::allNotifications);
|
||||
nsresult rv = searchSession->AddScopeTerm(nsMsgSearchScope::localNews, folder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return searchSession->Search(m_window);
|
||||
}
|
||||
|
||||
nsresult nsMsgDownloadAllNewsgroups::ProcessNextGroup()
|
||||
{
|
||||
bool done = false;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
done = !AdvanceToNextGroup();
|
||||
if (!done && m_currentFolder)
|
||||
{
|
||||
uint32_t folderFlags;
|
||||
m_currentFolder->GetFlags(&folderFlags);
|
||||
if (folderFlags & nsMsgFolderFlags::Offline)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (done)
|
||||
{
|
||||
if (m_listener)
|
||||
return m_listener->OnStopRunningUrl(nullptr, NS_OK);
|
||||
}
|
||||
m_downloadedHdrsForCurGroup = true;
|
||||
return m_currentFolder ? m_currentFolder->GetNewMessages(m_window, this) : NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsresult nsMsgDownloadAllNewsgroups::DownloadMsgsForCurrentGroup()
|
||||
{
|
||||
NS_ENSURE_TRUE(m_downloaderForGroup, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsCOMPtr <nsIMsgDatabase> db;
|
||||
nsCOMPtr <nsIMsgDownloadSettings> downloadSettings;
|
||||
m_currentFolder->GetMsgDatabase(getter_AddRefs(db));
|
||||
nsresult rv = m_currentFolder->GetDownloadSettings(getter_AddRefs(downloadSettings));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_currentFolder);
|
||||
if (newsFolder)
|
||||
newsFolder->SetSaveArticleOffline(true);
|
||||
|
||||
nsCOMPtr <nsIMsgSearchSession> searchSession = do_CreateInstance(NS_MSGSEARCHSESSION_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool downloadByDate, downloadUnreadOnly;
|
||||
uint32_t ageLimitOfMsgsToDownload;
|
||||
|
||||
downloadSettings->GetDownloadByDate(&downloadByDate);
|
||||
downloadSettings->GetDownloadUnreadOnly(&downloadUnreadOnly);
|
||||
downloadSettings->GetAgeLimitOfMsgsToDownload(&ageLimitOfMsgsToDownload);
|
||||
|
||||
nsCOMPtr <nsIMsgSearchTerm> term;
|
||||
nsCOMPtr <nsIMsgSearchValue> value;
|
||||
|
||||
rv = searchSession->CreateTerm(getter_AddRefs(term));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
term->GetValue(getter_AddRefs(value));
|
||||
|
||||
if (downloadUnreadOnly)
|
||||
{
|
||||
value->SetAttrib(nsMsgSearchAttrib::MsgStatus);
|
||||
value->SetStatus(nsMsgMessageFlags::Read);
|
||||
searchSession->AddSearchTerm(nsMsgSearchAttrib::MsgStatus, nsMsgSearchOp::Isnt, value, true, nullptr);
|
||||
}
|
||||
if (downloadByDate)
|
||||
{
|
||||
value->SetAttrib(nsMsgSearchAttrib::AgeInDays);
|
||||
value->SetAge(ageLimitOfMsgsToDownload);
|
||||
searchSession->AddSearchTerm(nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::IsLessThan, value, nsMsgSearchBooleanOp::BooleanAND, nullptr);
|
||||
}
|
||||
value->SetAttrib(nsMsgSearchAttrib::MsgStatus);
|
||||
value->SetStatus(nsMsgMessageFlags::Offline);
|
||||
searchSession->AddSearchTerm(nsMsgSearchAttrib::MsgStatus, nsMsgSearchOp::Isnt, value, nsMsgSearchBooleanOp::BooleanAND, nullptr);
|
||||
|
||||
m_downloaderForGroup->RunSearch(m_currentFolder, db, searchSession);
|
||||
return rv;
|
||||
}
|
||||
126
mailnews/news/src/nsNewsDownloader.h
Normal file
126
mailnews/news/src/nsNewsDownloader.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsNewsDownloader_H_
|
||||
#define _nsNewsDownloader_H_
|
||||
|
||||
|
||||
#include "nsIMsgDatabase.h"
|
||||
#include "nsIUrlListener.h"
|
||||
#include "nsIMsgFolder.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsIMsgSearchNotify.h"
|
||||
#include "nsIMsgSearchSession.h"
|
||||
|
||||
// base class for downloading articles in a single newsgroup. Keys to download are passed in
|
||||
// to DownloadArticles method.
|
||||
class nsNewsDownloader : public nsIUrlListener, public nsIMsgSearchNotify
|
||||
{
|
||||
public:
|
||||
nsNewsDownloader(nsIMsgWindow *window, nsIMsgDatabase *db, nsIUrlListener *listener);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURLLISTENER
|
||||
NS_DECL_NSIMSGSEARCHNOTIFY
|
||||
|
||||
virtual nsresult DownloadArticles(nsIMsgWindow *window, nsIMsgFolder *folder, nsTArray<nsMsgKey> *pKeyArray);
|
||||
|
||||
bool ShouldAbort() const { return m_abort; }
|
||||
|
||||
protected:
|
||||
virtual ~nsNewsDownloader();
|
||||
|
||||
virtual int32_t Write(const char * /*block*/, int32_t length) {return length;}
|
||||
virtual void Abort();
|
||||
virtual void Complete();
|
||||
virtual bool GetNextHdrToRetrieve();
|
||||
virtual nsresult DownloadNext(bool firstTimeP);
|
||||
virtual int32_t FinishDownload() {return 0;}
|
||||
virtual int32_t StartDownload() {return 0;}
|
||||
virtual nsresult ShowProgress(const char16_t *progressString, int32_t percent);
|
||||
|
||||
nsTArray<nsMsgKey> m_keysToDownload;
|
||||
nsCOMPtr <nsIMsgFolder> m_folder;
|
||||
nsCOMPtr <nsIMsgDatabase> m_newsDB;
|
||||
nsCOMPtr <nsIUrlListener> m_listener;
|
||||
bool m_downloadFromKeys;
|
||||
bool m_existedP;
|
||||
bool m_wroteAnyP;
|
||||
bool m_summaryValidP;
|
||||
bool m_abort;
|
||||
int32_t m_numwrote;
|
||||
nsMsgKey m_keyToDownload;
|
||||
nsCOMPtr <nsIMsgWindow> m_window;
|
||||
nsCOMPtr <nsIMsgStatusFeedback> m_statusFeedback;
|
||||
nsCOMPtr <nsIMsgSearchSession> m_searchSession;
|
||||
int32_t m_lastPercent;
|
||||
int64_t m_lastProgressTime;
|
||||
nsresult m_status;
|
||||
};
|
||||
|
||||
|
||||
// class for downloading articles in a single newsgroup to the offline store.
|
||||
class DownloadNewsArticlesToOfflineStore : public nsNewsDownloader
|
||||
{
|
||||
public:
|
||||
DownloadNewsArticlesToOfflineStore(nsIMsgWindow *window, nsIMsgDatabase *db, nsIUrlListener *listener);
|
||||
virtual ~DownloadNewsArticlesToOfflineStore();
|
||||
|
||||
NS_IMETHOD OnStartRunningUrl(nsIURI* url);
|
||||
NS_IMETHOD OnStopRunningUrl(nsIURI* url, nsresult exitCode);
|
||||
protected:
|
||||
virtual int32_t StartDownload();
|
||||
virtual int32_t FinishDownload();
|
||||
virtual bool GetNextHdrToRetrieve();
|
||||
|
||||
nsCOMPtr <nsISimpleEnumerator> m_headerEnumerator;
|
||||
nsCOMPtr <nsIMsgDBHdr> m_newsHeader;
|
||||
};
|
||||
|
||||
// class for downloading all the articles that match the passed in search criteria
|
||||
// for a single newsgroup.
|
||||
class DownloadMatchingNewsArticlesToNewsDB : public DownloadNewsArticlesToOfflineStore
|
||||
{
|
||||
public:
|
||||
DownloadMatchingNewsArticlesToNewsDB(nsIMsgWindow *window, nsIMsgFolder *folder, nsIMsgDatabase *newsDB, nsIUrlListener *listener);
|
||||
virtual ~DownloadMatchingNewsArticlesToNewsDB();
|
||||
nsresult RunSearch(nsIMsgFolder *folder, nsIMsgDatabase *newsDB, nsIMsgSearchSession *searchSession);
|
||||
protected:
|
||||
};
|
||||
|
||||
// this class iterates all the news servers for each group on the server that's configured for
|
||||
// offline use, downloads the messages that meet the download criteria for that newsgroup/server
|
||||
class nsMsgDownloadAllNewsgroups : public nsIUrlListener
|
||||
{
|
||||
public:
|
||||
nsMsgDownloadAllNewsgroups(nsIMsgWindow *window, nsIUrlListener *listener);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURLLISTENER
|
||||
|
||||
nsresult ProcessNextGroup();
|
||||
|
||||
protected:
|
||||
virtual ~nsMsgDownloadAllNewsgroups();
|
||||
|
||||
bool AdvanceToNextServer();
|
||||
bool AdvanceToNextGroup();
|
||||
nsresult DownloadMsgsForCurrentGroup();
|
||||
|
||||
DownloadMatchingNewsArticlesToNewsDB *m_downloaderForGroup;
|
||||
|
||||
nsCOMPtr <nsIMsgFolder> m_currentFolder;
|
||||
nsCOMPtr <nsIMsgWindow> m_window;
|
||||
nsCOMPtr <nsIArray> m_allServers;
|
||||
nsCOMPtr <nsIArray> m_allFolders;
|
||||
nsCOMPtr <nsIMsgIncomingServer> m_currentServer;
|
||||
nsCOMPtr <nsISimpleEnumerator> m_serverEnumerator;
|
||||
nsCOMPtr <nsIUrlListener> m_listener;
|
||||
|
||||
bool m_downloadedHdrsForCurGroup;
|
||||
};
|
||||
|
||||
#endif
|
||||
1897
mailnews/news/src/nsNewsFolder.cpp
Normal file
1897
mailnews/news/src/nsNewsFolder.cpp
Normal file
File diff suppressed because it is too large
Load diff
147
mailnews/news/src/nsNewsFolder.h
Normal file
147
mailnews/news/src/nsNewsFolder.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
Interface for representing News folders.
|
||||
*/
|
||||
|
||||
#ifndef nsMsgNewsFolder_h__
|
||||
#define nsMsgNewsFolder_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsMsgDBFolder.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsINntpIncomingServer.h" // need this for the IID
|
||||
#include "nsNewsUtils.h"
|
||||
#include "nsMsgKeySet.h"
|
||||
#include "nsIMsgNewsFolder.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIMsgFilterService.h"
|
||||
#include "nsIArray.h"
|
||||
|
||||
class nsMsgNewsFolder : public nsMsgDBFolder, public nsIMsgNewsFolder
|
||||
{
|
||||
public:
|
||||
nsMsgNewsFolder(void);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIMSGNEWSFOLDER
|
||||
|
||||
// nsIUrlListener method
|
||||
NS_IMETHOD OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode) override;
|
||||
// nsIMsgFolder methods:
|
||||
NS_IMETHOD GetSubFolders(nsISimpleEnumerator **aResult) override;
|
||||
|
||||
NS_IMETHOD GetMessages(nsISimpleEnumerator **result) override;
|
||||
NS_IMETHOD UpdateFolder(nsIMsgWindow *aWindow) override;
|
||||
|
||||
NS_IMETHOD CreateSubfolder(const nsAString& folderName,
|
||||
nsIMsgWindow *msgWindow) override;
|
||||
|
||||
NS_IMETHOD Delete() override;
|
||||
NS_IMETHOD Rename(const nsAString& newName,
|
||||
nsIMsgWindow *msgWindow) override;
|
||||
|
||||
NS_IMETHOD GetAbbreviatedName(nsAString& aAbbreviatedName) override;
|
||||
|
||||
NS_IMETHOD GetFolderURL(nsACString& url) override;
|
||||
|
||||
NS_IMETHOD GetExpungedBytesCount(int64_t *count);
|
||||
NS_IMETHOD GetDeletable(bool *deletable) override;
|
||||
|
||||
NS_IMETHOD RefreshSizeOnDisk();
|
||||
|
||||
NS_IMETHOD GetSizeOnDisk(int64_t *size) override;
|
||||
|
||||
NS_IMETHOD GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo,
|
||||
nsIMsgDatabase **db) override;
|
||||
|
||||
NS_IMETHOD DeleteMessages(nsIArray *messages,
|
||||
nsIMsgWindow *msgWindow, bool deleteStorage,
|
||||
bool isMove, nsIMsgCopyServiceListener* listener,
|
||||
bool allowUndo) override;
|
||||
NS_IMETHOD GetNewMessages(nsIMsgWindow *aWindow,
|
||||
nsIUrlListener *aListener) override;
|
||||
|
||||
NS_IMETHOD GetCanSubscribe(bool *aResult) override;
|
||||
NS_IMETHOD GetCanFileMessages(bool *aResult) override;
|
||||
NS_IMETHOD GetCanCreateSubfolders(bool *aResult) override;
|
||||
NS_IMETHOD GetCanRename(bool *aResult) override;
|
||||
NS_IMETHOD GetCanCompact(bool *aResult) override;
|
||||
NS_IMETHOD OnReadChanged(nsIDBChangeListener * aInstigator) override;
|
||||
|
||||
NS_IMETHOD DownloadMessagesForOffline(nsIArray *messages,
|
||||
nsIMsgWindow *window) override;
|
||||
NS_IMETHOD Compact(nsIUrlListener *aListener,
|
||||
nsIMsgWindow *aMsgWindow) override;
|
||||
NS_IMETHOD DownloadAllForOffline(nsIUrlListener *listener,
|
||||
nsIMsgWindow *msgWindow) override;
|
||||
NS_IMETHOD GetSortOrder(int32_t *order) override;
|
||||
NS_IMETHOD SetSortOrder(int32_t order) override;
|
||||
|
||||
NS_IMETHOD Shutdown(bool shutdownChildren) override;
|
||||
|
||||
NS_IMETHOD GetFilterList(nsIMsgWindow *aMsgWindow,
|
||||
nsIMsgFilterList **aFilterList) override;
|
||||
NS_IMETHOD GetEditableFilterList(nsIMsgWindow *aMsgWindow,
|
||||
nsIMsgFilterList **aFilterList) override;
|
||||
NS_IMETHOD SetFilterList(nsIMsgFilterList *aFilterList) override;
|
||||
NS_IMETHOD SetEditableFilterList(nsIMsgFilterList *aFilterList) override;
|
||||
NS_IMETHOD ApplyRetentionSettings() override;
|
||||
NS_IMETHOD GetIncomingServerType(nsACString& serverType) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsMsgNewsFolder();
|
||||
// helper routine to parse the URI and update member variables
|
||||
nsresult AbbreviatePrettyName(nsAString& prettyName, int32_t fullwords);
|
||||
nsresult ParseFolder(nsIFile *path);
|
||||
nsresult CreateSubFolders(nsIFile *path);
|
||||
nsresult AddDirectorySeparator(nsIFile *path);
|
||||
nsresult GetDatabase() override;
|
||||
virtual nsresult CreateChildFromURI(const nsCString &uri,
|
||||
nsIMsgFolder **folder) override;
|
||||
|
||||
nsresult LoadNewsrcFileAndCreateNewsgroups();
|
||||
int32_t RememberLine(const nsACString& line);
|
||||
nsresult RememberUnsubscribedGroup(const nsACString& newsgroup, const nsACString& setStr);
|
||||
nsresult ForgetLine(void);
|
||||
nsresult GetNewsMessages(nsIMsgWindow *aMsgWindow, bool getOld, nsIUrlListener *aListener);
|
||||
|
||||
int32_t HandleNewsrcLine(const char * line, uint32_t line_size);
|
||||
virtual nsresult CreateBaseMessageURI(const nsACString& aURI) override;
|
||||
|
||||
protected:
|
||||
int64_t mExpungedBytes;
|
||||
bool mGettingNews;
|
||||
bool mInitialized;
|
||||
bool m_downloadMessageForOfflineUse;
|
||||
bool m_downloadingMultipleMessages;
|
||||
|
||||
nsCString mOptionLines;
|
||||
nsCString mUnsubscribedNewsgroupLines;
|
||||
nsMsgKeySet *mReadSet;
|
||||
|
||||
nsCOMPtr<nsIFile> mNewsrcFilePath;
|
||||
|
||||
// used for auth news
|
||||
nsCString mGroupUsername;
|
||||
nsCString mGroupPassword;
|
||||
|
||||
// the name of the newsgroup.
|
||||
nsCString mRawName;
|
||||
int32_t mSortOrder;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Constructs a signon url for use in login manager.
|
||||
*
|
||||
* @param ref The URI ref (should be null unless working with legacy).
|
||||
* @param result The result of the string
|
||||
*/
|
||||
nsresult CreateNewsgroupUrlForSignon(const char *ref, nsAString &result);
|
||||
nsCOMPtr <nsIMsgFilterList> mFilterList;
|
||||
};
|
||||
|
||||
#endif // nsMsgNewsFolder_h__
|
||||
62
mailnews/news/src/nsNewsUtils.cpp
Normal file
62
mailnews/news/src/nsNewsUtils.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nntpCore.h"
|
||||
#include "nsNewsUtils.h"
|
||||
#include "nsMsgUtils.h"
|
||||
|
||||
|
||||
/* parses NewsMessageURI */
|
||||
nsresult
|
||||
nsParseNewsMessageURI(const char* uri, nsCString& group, nsMsgKey *key)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(uri);
|
||||
NS_ENSURE_ARG_POINTER(key);
|
||||
|
||||
nsAutoCString uriStr(uri);
|
||||
int32_t keySeparator = uriStr.FindChar('#');
|
||||
if(keySeparator != -1)
|
||||
{
|
||||
int32_t keyEndSeparator = MsgFindCharInSet(uriStr, "?&", keySeparator);
|
||||
|
||||
// Grab between the last '/' and the '#' for the key
|
||||
group = StringHead(uriStr, keySeparator);
|
||||
int32_t groupSeparator = group.RFind("/");
|
||||
if (groupSeparator == -1)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Our string APIs don't let us unescape into the same buffer from earlier,
|
||||
// so escape into a temporary
|
||||
nsAutoCString unescapedGroup;
|
||||
MsgUnescapeString(Substring(group, groupSeparator + 1), 0, unescapedGroup);
|
||||
group = unescapedGroup;
|
||||
|
||||
nsAutoCString keyStr;
|
||||
if (keyEndSeparator != -1)
|
||||
keyStr = Substring(uriStr, keySeparator + 1, keyEndSeparator - (keySeparator + 1));
|
||||
else
|
||||
keyStr = Substring(uriStr, keySeparator + 1);
|
||||
nsresult errorCode;
|
||||
*key = keyStr.ToInteger(&errorCode);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult nsCreateNewsBaseMessageURI(const char *baseURI, nsCString &baseMessageURI)
|
||||
{
|
||||
nsAutoCString tailURI(baseURI);
|
||||
|
||||
// chop off news:/
|
||||
if (tailURI.Find(kNewsRootURI) == 0)
|
||||
tailURI.Cut(0, PL_strlen(kNewsRootURI));
|
||||
|
||||
baseMessageURI = kNewsMessageRootURI;
|
||||
baseMessageURI += tailURI;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
33
mailnews/news/src/nsNewsUtils.h
Normal file
33
mailnews/news/src/nsNewsUtils.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef NS_NEWSUTILS_H
|
||||
#define NS_NEWSUTILS_H
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "MailNewsTypes2.h"
|
||||
|
||||
class nsIMsgNewsFolder;
|
||||
|
||||
#define kNewsRootURI "news:/"
|
||||
#define kNntpRootURI "nntp:/"
|
||||
#define kNewsMessageRootURI "news-message:/"
|
||||
#define kNewsURIGroupQuery "?group="
|
||||
#define kNewsURIKeyQuery "&key="
|
||||
|
||||
#define kNewsRootURILen 6
|
||||
#define kNntpRootURILen 6
|
||||
#define kNewsMessageRootURILen 14
|
||||
#define kNewsURIGroupQueryLen 7
|
||||
#define kNewsURIKeyQueryLen 5
|
||||
|
||||
extern nsresult
|
||||
nsParseNewsMessageURI(const char* uri, nsCString& group, nsMsgKey *key);
|
||||
|
||||
extern nsresult
|
||||
nsCreateNewsBaseMessageURI(const char *baseURI, nsCString &baseMessageURI);
|
||||
|
||||
#endif //NS_NEWSUTILS_H
|
||||
|
||||
2162
mailnews/news/src/nsNntpIncomingServer.cpp
Normal file
2162
mailnews/news/src/nsNntpIncomingServer.cpp
Normal file
File diff suppressed because it is too large
Load diff
142
mailnews/news/src/nsNntpIncomingServer.h
Normal file
142
mailnews/news/src/nsNntpIncomingServer.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsNntpIncomingServer_h
|
||||
#define __nsNntpIncomingServer_h
|
||||
|
||||
#include "nsINntpIncomingServer.h"
|
||||
#include "nsIUrlListener.h"
|
||||
#include "nscore.h"
|
||||
|
||||
#include "nsMsgIncomingServer.h"
|
||||
|
||||
#include "prmem.h"
|
||||
#include "plstr.h"
|
||||
#include "prprf.h"
|
||||
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsISubscribableServer.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsITreeView.h"
|
||||
#include "nsITreeSelection.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
#include "nsNntpMockChannel.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsINntpUrl;
|
||||
class nsIMsgMailNewsUrl;
|
||||
|
||||
/* get some implementation from nsMsgIncomingServer */
|
||||
class nsNntpIncomingServer : public nsMsgIncomingServer,
|
||||
public nsINntpIncomingServer,
|
||||
public nsIUrlListener,
|
||||
public nsISubscribableServer,
|
||||
public nsITreeView
|
||||
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINNTPINCOMINGSERVER
|
||||
NS_DECL_NSIURLLISTENER
|
||||
NS_DECL_NSISUBSCRIBABLESERVER
|
||||
NS_DECL_NSITREEVIEW
|
||||
|
||||
nsNntpIncomingServer();
|
||||
|
||||
NS_IMETHOD GetLocalStoreType(nsACString& type) override;
|
||||
NS_IMETHOD GetLocalDatabaseType(nsACString& type) override;
|
||||
NS_IMETHOD CloseCachedConnections() override;
|
||||
NS_IMETHOD PerformBiff(nsIMsgWindow *aMsgWindow) override;
|
||||
NS_IMETHOD PerformExpand(nsIMsgWindow *aMsgWindow) override;
|
||||
NS_IMETHOD OnUserOrHostNameChanged(const nsACString& oldName,
|
||||
const nsACString& newName,
|
||||
bool hostnameChanged) override;
|
||||
|
||||
// for nsMsgLineBuffer
|
||||
virtual nsresult HandleLine(const char *line, uint32_t line_size);
|
||||
|
||||
// override to clear all passwords associated with server
|
||||
NS_IMETHODIMP ForgetPassword() override;
|
||||
NS_IMETHOD GetCanSearchMessages(bool *canSearchMessages) override;
|
||||
NS_IMETHOD GetOfflineSupportLevel(int32_t *aSupportLevel) override;
|
||||
NS_IMETHOD GetDefaultCopiesAndFoldersPrefsToServer(bool *aCopiesAndFoldersOnServer) override;
|
||||
NS_IMETHOD GetCanCreateFoldersOnServer(bool *aCanCreateFoldersOnServer) override;
|
||||
NS_IMETHOD GetCanFileMessagesOnServer(bool *aCanFileMessagesOnServer) override;
|
||||
NS_IMETHOD GetFilterScope(nsMsgSearchScopeValue *filterScope) override;
|
||||
NS_IMETHOD GetSearchScope(nsMsgSearchScopeValue *searchScope) override;
|
||||
|
||||
NS_IMETHOD GetSocketType(int32_t *aSocketType) override; // override nsMsgIncomingServer impl
|
||||
NS_IMETHOD SetSocketType(int32_t aSocketType) override; // override nsMsgIncomingServer impl
|
||||
NS_IMETHOD GetSortOrder(int32_t* aSortOrder) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNntpIncomingServer();
|
||||
virtual nsresult CreateRootFolderFromUri(const nsCString &serverUri,
|
||||
nsIMsgFolder **rootFolder) override;
|
||||
nsresult GetNntpConnection(nsIURI *url, nsIMsgWindow *window,
|
||||
nsINNTPProtocol **aNntpConnection);
|
||||
nsresult CreateProtocolInstance(nsINNTPProtocol **aNntpConnection,
|
||||
nsIURI *url, nsIMsgWindow *window);
|
||||
bool ConnectionTimeOut(nsINNTPProtocol* aNntpConnection);
|
||||
nsCOMArray<nsINNTPProtocol> mConnectionCache;
|
||||
nsTArray<RefPtr<nsNntpMockChannel> > m_queuedChannels;
|
||||
|
||||
/**
|
||||
* Downloads the newsgroup headers.
|
||||
*/
|
||||
nsresult DownloadMail(nsIMsgWindow *aMsgWindow);
|
||||
|
||||
NS_IMETHOD GetServerRequiresPasswordForBiff(bool *aServerRequiresPasswordForBiff) override;
|
||||
nsresult SetupNewsrcSaveTimer();
|
||||
static void OnNewsrcSaveTimer(nsITimer *timer, void *voidIncomingServer);
|
||||
void WriteLine(nsIOutputStream *stream, nsCString &str);
|
||||
|
||||
private:
|
||||
nsTArray<nsCString> mSubscribedNewsgroups;
|
||||
nsTArray<nsCString> mGroupsOnServer;
|
||||
nsTArray<nsCString> mSubscribeSearchResult;
|
||||
bool mSearchResultSortDescending;
|
||||
// the list of of subscribed newsgroups within a given
|
||||
// subscribed dialog session.
|
||||
// we need to keep track of them so we know what to show as "checked"
|
||||
// in the search view
|
||||
nsTArray<nsCString> mTempSubscribed;
|
||||
nsCOMPtr<nsIAtom> mSubscribedAtom;
|
||||
nsCOMPtr<nsIAtom> mNntpAtom;
|
||||
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsCOMPtr<nsITreeSelection> mTreeSelection;
|
||||
|
||||
bool mHasSeenBeginGroups;
|
||||
bool mGetOnlyNew;
|
||||
nsresult WriteHostInfoFile();
|
||||
nsresult LoadHostInfoFile();
|
||||
nsresult AddGroupOnServer(const nsACString &name);
|
||||
|
||||
bool mNewsrcHasChanged;
|
||||
bool mHostInfoLoaded;
|
||||
bool mHostInfoHasChanged;
|
||||
nsCOMPtr <nsIFile> mHostInfoFile;
|
||||
|
||||
uint32_t mLastGroupDate;
|
||||
int32_t mUniqueId;
|
||||
uint32_t mLastUpdatedTime;
|
||||
int32_t mVersion;
|
||||
bool mPostingAllowed;
|
||||
|
||||
nsCOMPtr<nsITimer> mNewsrcSaveTimer;
|
||||
nsCOMPtr <nsIMsgWindow> mMsgWindow;
|
||||
|
||||
nsCOMPtr <nsISubscribableServer> mInner;
|
||||
nsresult EnsureInner();
|
||||
nsresult ClearInner();
|
||||
bool IsValidRow(int32_t row);
|
||||
nsCOMPtr<nsIFile> mNewsrcFilePath;
|
||||
};
|
||||
|
||||
#endif
|
||||
353
mailnews/news/src/nsNntpMockChannel.cpp
Normal file
353
mailnews/news/src/nsNntpMockChannel.cpp
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNntpMockChannel.h"
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsNNTPProtocol.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNntpMockChannel, nsIChannel, nsIRequest)
|
||||
|
||||
nsNntpMockChannel::nsNntpMockChannel(nsIURI *aUri, nsIMsgWindow *aMsgWindow)
|
||||
: m_url(aUri),
|
||||
m_msgWindow(aMsgWindow),
|
||||
m_channelState(CHANNEL_UNOPENED),
|
||||
m_protocol(nullptr),
|
||||
m_cancelStatus(NS_OK),
|
||||
m_loadFlags(0),
|
||||
m_contentLength(-1)
|
||||
{
|
||||
}
|
||||
|
||||
nsNntpMockChannel::nsNntpMockChannel(nsIURI *aUri, nsIMsgWindow *aMsgWindow,
|
||||
nsISupports *aConsumer)
|
||||
: m_url(aUri),
|
||||
m_context(aConsumer),
|
||||
m_msgWindow(aMsgWindow),
|
||||
m_channelState(CHANNEL_OPEN_WITH_LOAD),
|
||||
m_protocol(nullptr),
|
||||
m_cancelStatus(NS_OK),
|
||||
m_loadFlags(0),
|
||||
m_contentLength(-1)
|
||||
{
|
||||
}
|
||||
|
||||
nsNntpMockChannel::~nsNntpMockChannel()
|
||||
{
|
||||
}
|
||||
|
||||
#define FORWARD_CALL(function, argument) \
|
||||
if (m_protocol) \
|
||||
return m_protocol->function(argument);
|
||||
|
||||
////////////////////////
|
||||
// nsIRequest methods //
|
||||
////////////////////////
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetName(nsACString &result)
|
||||
{
|
||||
FORWARD_CALL(GetName, result)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::IsPending(bool *result)
|
||||
{
|
||||
FORWARD_CALL(IsPending, result)
|
||||
// We haven't been loaded yet, so we're still pending.
|
||||
*result = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetStatus(nsresult *status)
|
||||
{
|
||||
FORWARD_CALL(GetStatus, status)
|
||||
*status = m_cancelStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::Cancel(nsresult status)
|
||||
{
|
||||
m_cancelStatus = status;
|
||||
m_channelState = CHANNEL_CLOSED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::Suspend()
|
||||
{
|
||||
NS_NOTREACHED("nsNntpMockChannel::Suspend");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::Resume()
|
||||
{
|
||||
NS_NOTREACHED("nsNntpMockChannel::Resume");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
|
||||
{
|
||||
FORWARD_CALL(SetLoadGroup, aLoadGroup)
|
||||
m_loadGroup = aLoadGroup;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetLoadGroup(nsILoadGroup **aLoadGroup)
|
||||
{
|
||||
FORWARD_CALL(GetLoadGroup, aLoadGroup)
|
||||
NS_IF_ADDREF(*aLoadGroup = m_loadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
|
||||
{
|
||||
FORWARD_CALL(GetLoadFlags, aLoadFlags)
|
||||
*aLoadFlags = m_loadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
|
||||
{
|
||||
FORWARD_CALL(SetLoadFlags, aLoadFlags)
|
||||
m_loadFlags = aLoadFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetLoadInfo(nsILoadInfo **aLoadInfo)
|
||||
{
|
||||
FORWARD_CALL(GetLoadInfo, aLoadInfo)
|
||||
NS_IF_ADDREF(*aLoadInfo = m_loadInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::SetLoadInfo(nsILoadInfo *aLoadInfo)
|
||||
{
|
||||
FORWARD_CALL(SetLoadInfo, aLoadInfo)
|
||||
m_loadInfo = aLoadInfo;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// nsIChannel methods //
|
||||
////////////////////////
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetOriginalURI(nsIURI **aURI)
|
||||
{
|
||||
FORWARD_CALL(GetOriginalURI, aURI)
|
||||
NS_IF_ADDREF(*aURI = m_url);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::SetOriginalURI(nsIURI *aURI)
|
||||
{
|
||||
FORWARD_CALL(SetOriginalURI, aURI)
|
||||
// News does not seem to have the notion of an original URI.
|
||||
// (See bug 193317 and bug 1312314.)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetURI(nsIURI **aURI)
|
||||
{
|
||||
NS_IF_ADDREF(*aURI = m_url);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetOwner(nsISupports **owner)
|
||||
{
|
||||
FORWARD_CALL(GetOwner, owner)
|
||||
NS_IF_ADDREF(*owner = m_owner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::SetOwner(nsISupports *aOwner)
|
||||
{
|
||||
FORWARD_CALL(SetOwner, aOwner)
|
||||
m_owner = aOwner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::GetNotificationCallbacks(nsIInterfaceRequestor **callbacks)
|
||||
{
|
||||
FORWARD_CALL(GetNotificationCallbacks, callbacks)
|
||||
NS_IF_ADDREF(*callbacks = m_notificationCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
|
||||
{
|
||||
FORWARD_CALL(SetNotificationCallbacks, aCallbacks)
|
||||
m_notificationCallbacks = aCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetSecurityInfo(nsISupports **securityInfo)
|
||||
{
|
||||
FORWARD_CALL(GetSecurityInfo, securityInfo)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetContentType(nsACString &aContentType)
|
||||
{
|
||||
FORWARD_CALL(GetContentType, aContentType)
|
||||
aContentType = m_contentType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::SetContentType(const nsACString &aContentType)
|
||||
{
|
||||
FORWARD_CALL(SetContentType, aContentType)
|
||||
return NS_ParseResponseContentType(aContentType, m_contentType, m_contentCharset);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetContentCharset(nsACString &aCharset)
|
||||
{
|
||||
FORWARD_CALL(GetContentCharset, aCharset)
|
||||
aCharset = m_contentCharset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::SetContentCharset(const nsACString &aCharset)
|
||||
{
|
||||
FORWARD_CALL(SetContentCharset, aCharset)
|
||||
m_contentCharset = aCharset;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::GetContentDisposition(uint32_t *aContentDisposition)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::SetContentDisposition(uint32_t aContentDisposition)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::GetContentLength(int64_t *length)
|
||||
{
|
||||
FORWARD_CALL(GetContentLength, length)
|
||||
*length = m_contentLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpMockChannel::SetContentLength(int64_t aLength)
|
||||
{
|
||||
FORWARD_CALL(SetContentLength, aLength)
|
||||
m_contentLength = aLength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// nsIChannel and nsNNTPProtocol glue //
|
||||
////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::Open(nsIInputStream **_retval)
|
||||
{
|
||||
return NS_ImplementChannelOpen(this, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::Open2(nsIInputStream **_retval)
|
||||
{
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return Open(_retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::AsyncOpen(nsIStreamListener *listener,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
m_channelState = CHANNEL_OPEN_WITH_ASYNC;
|
||||
m_channelListener = listener;
|
||||
m_context = ctxt;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpMockChannel::AsyncOpen2(nsIStreamListener *aListener)
|
||||
{
|
||||
nsCOMPtr<nsIStreamListener> listener = aListener;
|
||||
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return AsyncOpen(listener, nullptr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNntpMockChannel::AttachNNTPConnection(nsNNTPProtocol &protocol)
|
||||
{
|
||||
// First things first. Were we canceled? If so, tell the protocol.
|
||||
if (m_channelState == CHANNEL_CLOSED || m_channelState == CHANNEL_UNOPENED)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
// We're going to active the protocol now. Note that if the user has
|
||||
// interacted with us through the nsIChannel API, we need to pass it to the
|
||||
// protocol instance. We also need to initialize it. For best results, we're
|
||||
// going to initialize the code and then set the values.
|
||||
nsresult rv = protocol.Initialize(m_url, m_msgWindow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Variable fun
|
||||
protocol.SetLoadGroup(m_loadGroup);
|
||||
protocol.SetLoadFlags(m_loadFlags);
|
||||
protocol.SetOwner(m_owner);
|
||||
protocol.SetNotificationCallbacks(m_notificationCallbacks);
|
||||
protocol.SetContentType(m_contentType);
|
||||
|
||||
// Now that we've set up the protocol, attach it to ourselves so that we can
|
||||
// forward all future calls to the protocol instance. We do not refcount this
|
||||
// instance, since the server will be owning all of them: once the server
|
||||
// releases its reference, the protocol instance is no longer usable anyways.
|
||||
m_protocol = &protocol;
|
||||
|
||||
switch (m_channelState)
|
||||
{
|
||||
case CHANNEL_OPEN_WITH_LOAD:
|
||||
rv = protocol.LoadNewsUrl(m_url, m_context);
|
||||
break;
|
||||
case CHANNEL_OPEN_WITH_ASYNC:
|
||||
rv = protocol.AsyncOpen(m_channelListener, m_context);
|
||||
break;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown channel state got us here.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// If we fail, that means that loading the NNTP protocol failed. Since we
|
||||
// essentially promised that we would load (by virtue of returning NS_OK to
|
||||
// AsyncOpen), we must now tell our listener the bad news.
|
||||
if (NS_FAILED(rv) && m_channelListener)
|
||||
m_channelListener->OnStopRequest(this, m_context, rv);
|
||||
|
||||
// Returning a failure code is our way of telling the server that this URL
|
||||
// isn't going to run, so it should give the connection the next URL in the
|
||||
// queue.
|
||||
return rv;
|
||||
}
|
||||
65
mailnews/news/src/nsNntpMockChannel.h
Normal file
65
mailnews/news/src/nsNntpMockChannel.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNntpMockChannel_h___
|
||||
#define nsNntpMockChannel_h___
|
||||
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
class nsNNTPProtocol;
|
||||
|
||||
class nsNntpMockChannel : public nsIChannel
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIREQUEST
|
||||
|
||||
nsNntpMockChannel(nsIURI *aUri, nsIMsgWindow *aMsgWindow);
|
||||
nsNntpMockChannel(nsIURI *aUri, nsIMsgWindow *aMsgWindow,
|
||||
nsISupports *aConsumer);
|
||||
|
||||
nsresult AttachNNTPConnection(nsNNTPProtocol &protocol);
|
||||
protected:
|
||||
virtual ~nsNntpMockChannel();
|
||||
|
||||
// The URL we will be running
|
||||
nsCOMPtr<nsIURI> m_url;
|
||||
|
||||
// Variables for arguments to pass into the opening phase.
|
||||
nsCOMPtr<nsIStreamListener> m_channelListener;
|
||||
nsCOMPtr<nsISupports> m_context;
|
||||
nsCOMPtr<nsIMsgWindow> m_msgWindow;
|
||||
|
||||
// The state we're in
|
||||
enum
|
||||
{
|
||||
CHANNEL_UNOPENED, //!< No one bothered to open this yet
|
||||
CHANNEL_OPEN_WITH_LOAD, //!< We should open with LoadNewsUrl
|
||||
CHANNEL_OPEN_WITH_ASYNC, //!< We should open with AsyncOpen
|
||||
CHANNEL_CLOSED //!< We were closed and should not open
|
||||
} m_channelState;
|
||||
|
||||
// The protocol instance
|
||||
nsNNTPProtocol *m_protocol;
|
||||
|
||||
// Temporary variables for accessors before we get to the actual instance.
|
||||
nsresult m_cancelStatus;
|
||||
nsCOMPtr<nsILoadGroup> m_loadGroup;
|
||||
nsCOMPtr<nsILoadInfo> m_loadInfo;
|
||||
nsLoadFlags m_loadFlags;
|
||||
|
||||
nsCOMPtr<nsISupports> m_owner;
|
||||
nsCOMPtr<nsIInterfaceRequestor> m_notificationCallbacks;
|
||||
nsCString m_contentType;
|
||||
nsCString m_contentCharset;
|
||||
int64_t m_contentLength;
|
||||
};
|
||||
|
||||
#endif // nsNntpMockChannel_h___
|
||||
1751
mailnews/news/src/nsNntpService.cpp
Normal file
1751
mailnews/news/src/nsNntpService.cpp
Normal file
File diff suppressed because it is too large
Load diff
76
mailnews/news/src/nsNntpService.h
Normal file
76
mailnews/news/src/nsNntpService.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNntpService_h___
|
||||
#define nsNntpService_h___
|
||||
|
||||
#include "nsINntpService.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIMsgMessageService.h"
|
||||
#include "nsINntpIncomingServer.h"
|
||||
#include "nsIMsgIncomingServer.h"
|
||||
#include "nsIFile.h"
|
||||
#include "MailNewsTypes.h"
|
||||
#include "nsIMsgProtocolInfo.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsINntpUrl.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContentHandler.h"
|
||||
#include "nsICacheStorage.h"
|
||||
|
||||
#include "nsICommandLineHandler.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIUrlListener;
|
||||
|
||||
class nsNntpService : public nsINntpService,
|
||||
public nsIMsgMessageService,
|
||||
public nsIMsgMessageFetchPartService,
|
||||
public nsIProtocolHandler,
|
||||
public nsIMsgProtocolInfo,
|
||||
public nsICommandLineHandler,
|
||||
public nsIContentHandler
|
||||
{
|
||||
public:
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSINNTPSERVICE
|
||||
NS_DECL_NSIMSGMESSAGESERVICE
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
NS_DECL_NSIMSGPROTOCOLINFO
|
||||
NS_DECL_NSICONTENTHANDLER
|
||||
NS_DECL_NSIMSGMESSAGEFETCHPARTSERVICE
|
||||
NS_DECL_NSICOMMANDLINEHANDLER
|
||||
|
||||
// nsNntpService
|
||||
nsNntpService();
|
||||
|
||||
protected:
|
||||
virtual ~nsNntpService();
|
||||
|
||||
nsresult GetNntpServerByAccount(const char *aAccountKey, nsIMsgIncomingServer **aNntpServer);
|
||||
nsresult SetUpNntpUrlForPosting(const char *aAccountKey, char **newsUrlSpec);
|
||||
nsresult FindHostFromGroup(nsCString &host, nsCString &groupName);
|
||||
nsresult FindServerWithNewsgroup(nsCString &host, nsCString &groupName);
|
||||
|
||||
nsresult CreateMessageIDURL(nsIMsgFolder *folder, nsMsgKey key, char **url);
|
||||
nsresult GetMessageFromUrl(nsIURI *aUrl, nsIMsgWindow *aMsgWindow, nsISupports *aDisplayConsumer);
|
||||
// a convience routine used to put together news urls
|
||||
nsresult ConstructNntpUrl(const char * urlString, nsIUrlListener *aUrlListener, nsIMsgWindow * aMsgWindow, const char *originalMessageUri, int32_t action, nsIURI ** aUrl);
|
||||
nsresult CreateNewsAccount(const char *aHostname, bool aIsSecure, int32_t aPort, nsIMsgIncomingServer **aServer);
|
||||
nsresult GetServerForUri(nsIURI *aUri, nsINntpIncomingServer **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);
|
||||
nsresult DecomposeNewsMessageURI(const char * aMessageURI, nsIMsgFolder ** aFolder, nsMsgKey *aMsgKey);
|
||||
|
||||
bool mPrintingOperation; // Flag for printing operations
|
||||
bool mOpenAttachmentOperation; // Flag for opening attachments
|
||||
|
||||
nsCOMPtr<nsICacheStorage> mCacheStorage; // the cache storage used by news
|
||||
};
|
||||
|
||||
#endif /* nsNntpService_h___ */
|
||||
578
mailnews/news/src/nsNntpUrl.cpp
Normal file
578
mailnews/news/src/nsNntpUrl.cpp
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "msgCore.h" // precompiled header...
|
||||
|
||||
#include "nsIURL.h"
|
||||
#include "nsNntpUrl.h"
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsNewsUtils.h"
|
||||
#include "nsMsgUtils.h"
|
||||
|
||||
#include "nntpCore.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIMsgDatabase.h"
|
||||
#include "nsMsgDBCID.h"
|
||||
#include "nsMsgNewsCID.h"
|
||||
#include "nsIMsgFolder.h"
|
||||
#include "nsIMsgNewsFolder.h"
|
||||
#include "nsINntpService.h"
|
||||
#include "nsIMsgMessageService.h"
|
||||
#include "nsIMsgAccountManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
|
||||
nsNntpUrl::nsNntpUrl()
|
||||
{
|
||||
m_newsgroupPost = nullptr;
|
||||
m_newsAction = nsINntpUrl::ActionUnknown;
|
||||
m_addDummyEnvelope = false;
|
||||
m_canonicalLineEnding = false;
|
||||
m_filePath = nullptr;
|
||||
m_getOldMessages = false;
|
||||
m_key = nsMsgKey_None;
|
||||
}
|
||||
|
||||
nsNntpUrl::~nsNntpUrl()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsNntpUrl, nsMsgMailNewsUrl)
|
||||
NS_IMPL_RELEASE_INHERITED(nsNntpUrl, nsMsgMailNewsUrl)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsNntpUrl)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsINntpUrl)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINntpUrl)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMsgMessageUrl)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMsgI18NUrl)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsMsgMailNewsUrl)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Begin nsINntpUrl specific support
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* News URI parsing explanation:
|
||||
* We support 3 different news URI schemes, essentially boiling down to 8
|
||||
* different formats:
|
||||
* news://host/group
|
||||
* news://host/message
|
||||
* news://host/
|
||||
* news:group
|
||||
* news:message
|
||||
* nntp://host/group
|
||||
* nntp://host/group/key
|
||||
* news-message://host/group#key
|
||||
*
|
||||
* In addition, we use queries on the news URIs with authorities for internal
|
||||
* NNTP processing. The most important one is ?group=group&key=key, for cache
|
||||
* canonicalization.
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::SetSpec(const nsACString &aSpec)
|
||||
{
|
||||
// For [s]news: URIs, we need to munge the spec if it is no authority, because
|
||||
// the URI parser guesses the wrong thing otherwise
|
||||
nsCString parseSpec(aSpec);
|
||||
int32_t colon = parseSpec.Find(":");
|
||||
|
||||
// Our smallest scheme is 4 characters long, so colon must be at least 4
|
||||
if (colon < 4 || colon + 1 == (int32_t) parseSpec.Length())
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
if (Substring(parseSpec, colon - 4, 4).EqualsLiteral("news") &&
|
||||
parseSpec[colon + 1] != '/')
|
||||
{
|
||||
// To make this parse properly, we add in three slashes, which convinces the
|
||||
// parser that the authority component is empty.
|
||||
parseSpec = Substring(aSpec, 0, colon + 1);
|
||||
parseSpec.AppendLiteral("///");
|
||||
parseSpec += Substring(aSpec, colon + 1);
|
||||
}
|
||||
|
||||
nsresult rv = nsMsgMailNewsUrl::SetSpec(parseSpec);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsAutoCString scheme;
|
||||
rv = GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (scheme.EqualsLiteral("news") || scheme.EqualsLiteral("snews"))
|
||||
rv = ParseNewsURL();
|
||||
else if (scheme.EqualsLiteral("nntp") || scheme.EqualsLiteral("nntps"))
|
||||
rv = ParseNntpURL();
|
||||
else if (scheme.EqualsLiteral("news-message"))
|
||||
{
|
||||
nsAutoCString spec;
|
||||
rv = GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = nsParseNewsMessageURI(spec.get(), m_group, &m_key);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_MALFORMED_URI);
|
||||
}
|
||||
else
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = DetermineNewsAction();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsNntpUrl::ParseNewsURL()
|
||||
{
|
||||
// The path here is the group/msgid portion
|
||||
nsAutoCString path;
|
||||
nsresult rv = GetFilePath(path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Drop the potential beginning from the path
|
||||
if (path.Length() && path[0] == '/')
|
||||
path = Substring(path, 1);
|
||||
|
||||
// The presence of an `@' is a sign we have a msgid
|
||||
if (path.Find("@") != -1 || path.Find("%40") != -1)
|
||||
{
|
||||
MsgUnescapeString(path, 0, m_messageID);
|
||||
|
||||
// Set group, key for ?group=foo&key=123 uris
|
||||
nsAutoCString spec;
|
||||
rv = GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
int32_t groupPos = spec.Find(kNewsURIGroupQuery); // find ?group=
|
||||
int32_t keyPos = spec.Find(kNewsURIKeyQuery); // find &key=
|
||||
if (groupPos != kNotFound && keyPos != kNotFound)
|
||||
{
|
||||
// get group name and message key
|
||||
m_group = Substring(spec, groupPos + kNewsURIGroupQueryLen,
|
||||
keyPos - groupPos - kNewsURIGroupQueryLen);
|
||||
nsCString keyStr(Substring(spec, keyPos + kNewsURIKeyQueryLen));
|
||||
m_key = keyStr.ToInteger(&rv, 10);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_MALFORMED_URI);
|
||||
}
|
||||
}
|
||||
else
|
||||
MsgUnescapeString(path, 0, m_group);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNntpUrl::ParseNntpURL()
|
||||
{
|
||||
nsAutoCString path;
|
||||
nsresult rv = GetFilePath(path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (path.Length() > 0 && path[0] == '/')
|
||||
path = Substring(path, 1);
|
||||
|
||||
if (path.IsEmpty())
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
int32_t slash = path.FindChar('/');
|
||||
if (slash == -1)
|
||||
{
|
||||
m_group = path;
|
||||
m_key = nsMsgKey_None;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_group = Substring(path, 0, slash);
|
||||
nsAutoCString keyStr;
|
||||
keyStr = Substring(path, slash + 1);
|
||||
m_key = keyStr.ToInteger(&rv, 10);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_MALFORMED_URI);
|
||||
|
||||
// Keys must be at least one
|
||||
if (m_key == 0)
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNntpUrl::DetermineNewsAction()
|
||||
{
|
||||
nsAutoCString path;
|
||||
nsresult rv = nsMsgMailNewsUrl::GetPath(path);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsAutoCString query;
|
||||
rv = GetQuery(query);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (query.EqualsLiteral("cancel"))
|
||||
{
|
||||
m_newsAction = nsINntpUrl::ActionCancelArticle;
|
||||
return NS_OK;
|
||||
}
|
||||
if (query.EqualsLiteral("list-ids"))
|
||||
{
|
||||
m_newsAction = nsINntpUrl::ActionListIds;
|
||||
return NS_OK;
|
||||
}
|
||||
if (query.EqualsLiteral("newgroups"))
|
||||
{
|
||||
m_newsAction = nsINntpUrl::ActionListNewGroups;
|
||||
return NS_OK;
|
||||
}
|
||||
if (StringBeginsWith(query, NS_LITERAL_CSTRING("search")))
|
||||
{
|
||||
m_newsAction = nsINntpUrl::ActionSearch;
|
||||
return NS_OK;
|
||||
}
|
||||
if (StringBeginsWith(query, NS_LITERAL_CSTRING("part=")) ||
|
||||
query.Find("&part=") > 0)
|
||||
{
|
||||
// news://news.mozilla.org:119/3B98D201.3020100%40cs.com?part=1
|
||||
// news://news.mozilla.org:119/b58dme%24aia2%40ripley.netscape.com?header=print&part=1.2&type=image/jpeg&filename=Pole.jpg
|
||||
m_newsAction = nsINntpUrl::ActionFetchPart;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!m_messageID.IsEmpty() || m_key != nsMsgKey_None)
|
||||
{
|
||||
m_newsAction = nsINntpUrl::ActionFetchArticle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (m_group.Find("*") >= 0)
|
||||
{
|
||||
// If the group is a wildmat, list groups instead of grabbing a group.
|
||||
m_newsAction = nsINntpUrl::ActionListGroups;
|
||||
return NS_OK;
|
||||
}
|
||||
if (!m_group.IsEmpty())
|
||||
{
|
||||
m_newsAction = nsINntpUrl::ActionGetNewNews;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// At this point, we have a URI that contains neither a query, a group, nor a
|
||||
// message ID. Ergo, we don't know what it is.
|
||||
m_newsAction = nsINntpUrl::ActionUnknown;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::SetGetOldMessages(bool aGetOldMessages)
|
||||
{
|
||||
m_getOldMessages = aGetOldMessages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetGetOldMessages(bool * aGetOldMessages)
|
||||
{
|
||||
NS_ENSURE_ARG(aGetOldMessages);
|
||||
*aGetOldMessages = m_getOldMessages;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetNewsAction(nsNewsAction *aNewsAction)
|
||||
{
|
||||
if (aNewsAction)
|
||||
*aNewsAction = m_newsAction;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::SetNewsAction(nsNewsAction aNewsAction)
|
||||
{
|
||||
m_newsAction = aNewsAction;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetGroup(nsACString &group)
|
||||
{
|
||||
group = m_group;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetMessageID(nsACString &messageID)
|
||||
{
|
||||
messageID = m_messageID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetKey(nsMsgKey *key)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(key);
|
||||
*key = m_key;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetPrincipalSpec(nsACString& aPrincipalSpec)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::SetUri(const char * 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()) {
|
||||
nsAutoCString spec;
|
||||
rv = GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
mURI = spec;
|
||||
}
|
||||
|
||||
*aURI = ToNewCString(mURI);
|
||||
if (!*aURI) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_GETSET(nsNntpUrl, AddDummyEnvelope, bool, m_addDummyEnvelope)
|
||||
NS_IMPL_GETSET(nsNntpUrl, CanonicalLineEnding, bool, m_canonicalLineEnding)
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::SetMessageFile(nsIFile * aFile)
|
||||
{
|
||||
m_messageFile = aFile;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetMessageFile(nsIFile ** aFile)
|
||||
{
|
||||
if (aFile)
|
||||
NS_IF_ADDREF(*aFile = m_messageFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// End nsINntpUrl specific support
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult nsNntpUrl::SetMessageToPost(nsINNTPNewsgroupPost *post)
|
||||
{
|
||||
m_newsgroupPost = post;
|
||||
if (post)
|
||||
SetNewsAction(nsINntpUrl::ActionPostArticle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsNntpUrl::GetMessageToPost(nsINNTPNewsgroupPost **aPost)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPost);
|
||||
NS_IF_ADDREF(*aPost = m_newsgroupPost);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::SetMessageHeader(nsIMsgDBHdr *aMsgHdr)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetMessageHeader(nsIMsgDBHdr ** aMsgHdr)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr <nsINntpService> nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr <nsIMsgMessageService> msgService = do_QueryInterface(nntpService, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsAutoCString spec(mOriginalSpec);
|
||||
if (spec.IsEmpty()) {
|
||||
// Handle the case where necko directly runs an internal news:// URL,
|
||||
// one that looks like news://host/message-id?group=mozilla.announce&key=15
|
||||
// Other sorts of URLs -- e.g. news://host/message-id -- will not succeed.
|
||||
rv = GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return msgService->MessageURIToMsgHdr(spec.get(), aMsgHdr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::IsUrlType(uint32_t type, bool *isType)
|
||||
{
|
||||
NS_ENSURE_ARG(isType);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case nsIMsgMailNewsUrl::eDisplay:
|
||||
*isType = (m_newsAction == nsINntpUrl::ActionFetchArticle);
|
||||
break;
|
||||
default:
|
||||
*isType = false;
|
||||
};
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpUrl::GetOriginalSpec(char **aSpec)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSpec);
|
||||
*aSpec = ToNewCString(mOriginalSpec);
|
||||
if (!*aSpec) return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpUrl::SetOriginalSpec(const char *aSpec)
|
||||
{
|
||||
mOriginalSpec = aSpec;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpUrl::GetServer(nsIMsgIncomingServer **aServer)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aServer);
|
||||
|
||||
nsresult rv;
|
||||
nsAutoCString scheme, user, host;
|
||||
|
||||
GetScheme(scheme);
|
||||
GetUsername(user);
|
||||
GetHost(host);
|
||||
|
||||
// No authority -> no server
|
||||
if (host.IsEmpty())
|
||||
{
|
||||
*aServer = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Looking up the server...
|
||||
// news-message is used purely internally, so it can never refer to the real
|
||||
// attribute. nntp is never used internally, so it probably refers to the real
|
||||
// one. news is used both internally and externally, so it could refer to
|
||||
// either one. We'll assume it's an internal one first, though.
|
||||
bool isNews = scheme.EqualsLiteral("news") || scheme.EqualsLiteral("snews");
|
||||
bool isNntp = scheme.EqualsLiteral("nntp") || scheme.EqualsLiteral("nntps");
|
||||
|
||||
bool tryReal = isNntp;
|
||||
|
||||
nsCOMPtr<nsIMsgAccountManager> accountManager =
|
||||
do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Ignoring return results: it is perfectly acceptable for the server to not
|
||||
// exist, but FindServer (and not FindRealServer) throws NS_ERROR_UNEXPECTED
|
||||
// in this case.
|
||||
*aServer = nullptr;
|
||||
if (tryReal)
|
||||
accountManager->FindRealServer(user, host, NS_LITERAL_CSTRING("nntp"), 0,
|
||||
aServer);
|
||||
else
|
||||
accountManager->FindServer(user, host, NS_LITERAL_CSTRING("nntp"), aServer);
|
||||
if (!*aServer && (isNews || isNntp))
|
||||
{
|
||||
// Didn't find it, try the other option
|
||||
if (tryReal)
|
||||
accountManager->FindServer(user, host, NS_LITERAL_CSTRING("nntp"),
|
||||
aServer);
|
||||
else
|
||||
accountManager->FindRealServer(user, host, NS_LITERAL_CSTRING("nntp"), 0,
|
||||
aServer);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetFolder(nsIMsgFolder **msgFolder)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(msgFolder);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
rv = GetServer(getter_AddRefs(server));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Need a server and a group to get the folder
|
||||
if (!server || m_group.IsEmpty())
|
||||
{
|
||||
*msgFolder = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the group on the server
|
||||
nsCOMPtr<nsINntpIncomingServer> nntpServer = do_QueryInterface(server, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool hasGroup = false;
|
||||
rv = nntpServer->ContainsNewsgroup(m_group, &hasGroup);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!hasGroup)
|
||||
{
|
||||
*msgFolder = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMsgNewsFolder> newsFolder;
|
||||
rv = nntpServer->FindGroup(m_group, getter_AddRefs(newsFolder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return newsFolder->QueryInterface(NS_GET_IID(nsIMsgFolder), (void**)msgFolder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNntpUrl::GetFolderCharset(char **aCharacterSet)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> folder;
|
||||
nsresult rv = GetFolder(getter_AddRefs(folder));
|
||||
// don't assert here. this can happen if there is no message folder
|
||||
// like when we display a news://host/message-id url
|
||||
if (NS_FAILED(rv) || !folder)
|
||||
return rv;
|
||||
nsCString tmpStr;
|
||||
rv = folder->GetCharset(tmpStr);
|
||||
*aCharacterSet = ToNewCString(tmpStr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetFolderCharsetOverride(bool * aCharacterSetOverride)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> folder;
|
||||
nsresult rv = GetFolder(getter_AddRefs(folder));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
NS_ENSURE_TRUE(folder, NS_ERROR_FAILURE);
|
||||
rv = folder->GetCharsetOverride(aCharacterSetOverride);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::GetCharsetOverRide(char ** aCharacterSet)
|
||||
{
|
||||
if (!mCharsetOverride.IsEmpty())
|
||||
*aCharacterSet = ToNewCString(mCharsetOverride);
|
||||
else
|
||||
*aCharacterSet = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::SetCharsetOverRide(const char * aCharacterSet)
|
||||
{
|
||||
mCharsetOverride = aCharacterSet;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNntpUrl::CloneInternal(uint32_t aRefHandlingMode,
|
||||
const nsACString& newRef,
|
||||
nsIURI **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
rv = nsMsgMailNewsUrl::CloneInternal(aRefHandlingMode, newRef, _retval);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIMsgMessageUrl> newsurl = do_QueryInterface(*_retval, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return newsurl->SetUri(mURI.get());
|
||||
}
|
||||
|
||||
64
mailnews/news/src/nsNntpUrl.h
Normal file
64
mailnews/news/src/nsNntpUrl.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsNntpUrl_h__
|
||||
#define nsNntpUrl_h__
|
||||
|
||||
#include "nsINntpUrl.h"
|
||||
#include "nsMsgMailNewsUrl.h"
|
||||
#include "nsINNTPNewsgroupPost.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
class nsNntpUrl : public nsINntpUrl, public nsMsgMailNewsUrl, public nsIMsgMessageUrl, public nsIMsgI18NUrl
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSINNTPURL
|
||||
NS_DECL_NSIMSGMESSAGEURL
|
||||
NS_DECL_NSIMSGI18NURL
|
||||
|
||||
// nsIURI over-ride...
|
||||
NS_IMETHOD SetSpec(const nsACString &aSpec) override;
|
||||
|
||||
NS_IMETHOD IsUrlType(uint32_t type, bool *isType) override;
|
||||
|
||||
// nsIMsgMailNewsUrl overrides
|
||||
NS_IMETHOD GetServer(nsIMsgIncomingServer **server) override;
|
||||
NS_IMETHOD GetFolder(nsIMsgFolder **msgFolder) override;
|
||||
NS_IMETHOD CloneInternal(uint32_t aRefHandlingMode,
|
||||
const nsACString& newRef,nsIURI **_retval) override;
|
||||
|
||||
// nsNntpUrl
|
||||
nsNntpUrl();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
private:
|
||||
virtual ~nsNntpUrl();
|
||||
nsresult DetermineNewsAction();
|
||||
nsresult ParseNewsURL();
|
||||
nsresult ParseNntpURL();
|
||||
|
||||
nsCOMPtr<nsINNTPNewsgroupPost> m_newsgroupPost;
|
||||
nsNewsAction m_newsAction; // the action this url represents...parse mailbox, display messages, etc.
|
||||
|
||||
nsCString mURI; // the RDF URI associated with this url.
|
||||
nsCString mCharsetOverride; // used by nsIMsgI18NUrl...
|
||||
|
||||
nsCString mOriginalSpec;
|
||||
nsCOMPtr <nsIFile> m_filePath;
|
||||
|
||||
// used by save message to disk
|
||||
nsCOMPtr<nsIFile> m_messageFile;
|
||||
|
||||
bool m_addDummyEnvelope;
|
||||
bool m_canonicalLineEnding;
|
||||
bool m_getOldMessages;
|
||||
|
||||
nsCString m_group;
|
||||
nsCString m_messageID;
|
||||
nsMsgKey m_key;
|
||||
};
|
||||
|
||||
#endif // nsNntpUrl_h__
|
||||
Loading…
Add table
Add a link
Reference in a new issue