Backout out patch for bug 16913 due to regressions (see bug 424607 for details); a=blocking-3.0a1+
git-svn-id: svn://10.0.0.236/trunk@250968 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -52,9 +52,7 @@ enterPasswordTitle=News Server Password Required
|
||||
okButtonText=Download
|
||||
|
||||
noNewMessages=There are no new messages on the server.
|
||||
# The difference between these two is that the second one is shown when processing XHDR commands
|
||||
downloadingHeaders=Downloading %S of %S headers
|
||||
downloadingFilterHeaders=Getting filter headers: %S (%S/%S)
|
||||
downloadingArticles=Downloading articles %S-%S
|
||||
bytesReceived=Downloading newsgroups: %S received (%SKB read at %SKB/sec)
|
||||
checkingForNewNews=Checking newsgroup %S of %S on %S for new messages
|
||||
|
||||
@@ -1015,15 +1015,11 @@ NS_IMETHODIMP nsMsgSearchValidityManager::GetTable (int whichTable, nsIMsgSearch
|
||||
case nsMsgSearchScope::news:
|
||||
if (!m_newsTable)
|
||||
rv = InitNewsTable();
|
||||
if (m_newsTable)
|
||||
rv = SetOtherHeadersInTable(m_newsTable, customHeaders.get());
|
||||
*ppOutTable = m_newsTable;
|
||||
break;
|
||||
case nsMsgSearchScope::newsFilter:
|
||||
if (!m_newsFilterTable)
|
||||
rv = InitNewsFilterTable();
|
||||
if (m_newsFilterTable)
|
||||
rv = SetOtherHeadersInTable(m_newsFilterTable, customHeaders.get());
|
||||
*ppOutTable = m_newsFilterTable;
|
||||
break;
|
||||
case nsMsgSearchScope::localNews:
|
||||
|
||||
@@ -144,14 +144,8 @@ char *nsMsgSearchNews::EncodeTerm (nsIMsgSearchTerm *term)
|
||||
attribEncoding = m_kNntpSubject;
|
||||
break;
|
||||
default:
|
||||
nsCString header;
|
||||
term->GetArbitraryHeader(header);
|
||||
if (header.IsEmpty())
|
||||
{
|
||||
NS_ASSERTION(PR_FALSE,"malformed search"); // malformed search term?
|
||||
return nsnull;
|
||||
}
|
||||
attribEncoding = header.get();
|
||||
NS_ASSERTION(PR_FALSE,"malformed search"); // malformed search term?
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Build a string to represent the string pattern
|
||||
@@ -466,23 +460,6 @@ nsresult nsMsgSearchValidityManager::InitNewsTable()
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::Subject, nsMsgSearchOp::BeginsWith, 1);
|
||||
m_newsTable->SetAvailable (nsMsgSearchAttrib::Subject, nsMsgSearchOp::EndsWith, 1);
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::Subject, nsMsgSearchOp::EndsWith, 1);
|
||||
|
||||
#if 0
|
||||
// Size should be handled after the fact...
|
||||
m_newsTable->SetAvailable (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsGreaterThan, 1);
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsGreaterThan, 1);
|
||||
m_newsTable->SetAvailable (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsLessThan, 1);
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsLessThan, 1);
|
||||
#endif
|
||||
|
||||
m_newsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
|
||||
m_newsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
|
||||
m_newsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
|
||||
m_newsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
|
||||
m_newsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@@ -534,20 +511,6 @@ nsresult nsMsgSearchValidityManager::InitNewsFilterTable()
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Date, nsMsgSearchOp::Is, 1);
|
||||
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::Date, nsMsgSearchOp::Isnt, 1);
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Date, nsMsgSearchOp::Isnt, 1);
|
||||
|
||||
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsGreaterThan, 1);
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsGreaterThan, 1);
|
||||
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsLessThan, 1);
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Size, nsMsgSearchOp::IsLessThan, 1);
|
||||
|
||||
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
|
||||
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
|
||||
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
|
||||
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
|
||||
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
@@ -73,19 +73,11 @@ interface nsINNTPNewsgroupList : nsISupports {
|
||||
/* the XOVER Sink should maintain the ListNewsGroupState */
|
||||
void initXOVER(in long first_message, in long last_message);
|
||||
void processXOVERLINE(in string line, out unsigned long status);
|
||||
void processNonXOVER(in string line);
|
||||
void resetXOVER();
|
||||
void finishXOVERLINE(in long status, out long newstatus);
|
||||
void clearXOVERState();
|
||||
|
||||
ACString initXHDR();
|
||||
void processXHDRLine(in ACString line);
|
||||
|
||||
void initHEAD(in long message);
|
||||
void processHEADLine(in ACString line);
|
||||
|
||||
// Calls the entire header process
|
||||
void callFilters();
|
||||
|
||||
attribute boolean getOldMessages;
|
||||
};
|
||||
|
||||
|
||||
@@ -127,35 +127,6 @@ nsNNTPNewsgroupList::Initialize(nsINntpUrl *runningURL, nsIMsgNewsFolder *newsFo
|
||||
m_runningURL = runningURL;
|
||||
m_knownArts.set = nsMsgKeySet::Create();
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr <nsIMsgFolder> folder = do_QueryInterface(m_newsFolder, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = folder->GetFilterList(m_msgWindow, getter_AddRefs(m_filterList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
nsCString ngHeaders;
|
||||
m_filterList->GetArbitraryHeaders(ngHeaders);
|
||||
m_filterHeaders.ParseString(ngHeaders.get(), " ");
|
||||
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
rv = folder->GetServer(getter_AddRefs(server));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = server->GetFilterList(m_msgWindow, getter_AddRefs(m_serverFilterList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
nsCAutoString servHeaders;
|
||||
m_serverFilterList->GetArbitraryHeaders(servHeaders);
|
||||
|
||||
nsCStringArray servArray;
|
||||
servArray.ParseString(servHeaders.get(), " ");
|
||||
|
||||
// servArray may have duplicates already in m_filterHeaders.
|
||||
for (PRInt32 i = 0; i < servArray.Count(); i++)
|
||||
{
|
||||
if (m_filterHeaders.IndexOf(*(servArray[i])) == -1)
|
||||
m_filterHeaders.AppendCString(*(servArray[i]));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -180,8 +151,9 @@ nsNNTPNewsgroupList::CleanUp()
|
||||
if (lastMissingCheck)
|
||||
firstKnown = lastMissingCheck + 1;
|
||||
}
|
||||
PRBool done = firstKnown > lastKnown; // just in case...
|
||||
PRBool foundMissingArticle = PR_FALSE;
|
||||
while (firstKnown <= lastKnown)
|
||||
while (!done)
|
||||
{
|
||||
PRInt32 firstUnreadStart, firstUnreadEnd;
|
||||
m_set->FirstMissingRange(firstKnown, lastKnown, &firstUnreadStart, &firstUnreadEnd);
|
||||
@@ -520,13 +492,12 @@ nsNNTPNewsgroupList::InitXOVER(PRInt32 first_msg, PRInt32 last_msg)
|
||||
m_firstMsgNumber = first_msg;
|
||||
m_lastMsgNumber = last_msg;
|
||||
m_lastProcessedNumber = first_msg > 1 ? first_msg - 1 : 1;
|
||||
m_currentXHDRIndex = -1;
|
||||
return status;
|
||||
}
|
||||
|
||||
// from RFC 822, don't translate
|
||||
#define FROM_HEADER "From: "
|
||||
#define SUBJECT_HEADER "Subject: "
|
||||
#define SUBECT_HEADER "Subject: "
|
||||
#define DATE_HEADER "Date: "
|
||||
|
||||
nsresult
|
||||
@@ -641,7 +612,136 @@ nsNNTPNewsgroupList::ParseLine(char *line, PRUint32 * message_number)
|
||||
|
||||
GET_TOKEN (); /* xref */
|
||||
|
||||
return m_newsDB->AddNewHdrToDB(newMsgHdr, PR_TRUE);
|
||||
// apply filters
|
||||
// XXX TODO
|
||||
// do spam classification for news
|
||||
|
||||
nsCOMPtr <nsIMsgFolder> folder = do_QueryInterface(m_newsFolder, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (!m_filterList)
|
||||
{
|
||||
rv = folder->GetFilterList(m_msgWindow, getter_AddRefs(m_filterList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
if (!m_serverFilterList)
|
||||
{
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
rv = folder->GetServer(getter_AddRefs(server));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = server->GetFilterList(m_msgWindow, getter_AddRefs(m_serverFilterList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// flag for kill
|
||||
// if the action is Delete, and we get a hit (see ApplyFilterHit())
|
||||
// we set this to PR_FALSE. if false, we won't add it to the db.
|
||||
m_addHdrToDB = PR_TRUE;
|
||||
|
||||
PRUint32 filterCount = 0;
|
||||
if (m_filterList) {
|
||||
rv = m_filterList->GetFilterCount(&filterCount);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
PRUint32 serverFilterCount = 0;
|
||||
if (m_serverFilterList) {
|
||||
rv = m_serverFilterList->GetFilterCount(&serverFilterCount);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// only do this if we have filters
|
||||
if (filterCount || serverFilterCount)
|
||||
{
|
||||
// build up a "headers" for filter code
|
||||
nsCString subject;
|
||||
rv = newMsgHdr->GetSubject(getter_Copies(subject));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
PRUint32 headersSize = 0;
|
||||
|
||||
// +1 to separate headers with a null byte
|
||||
if (authorStr)
|
||||
headersSize += strlen(FROM_HEADER) + strlen(authorStr) + 1;
|
||||
|
||||
if (!(subject.IsEmpty()))
|
||||
headersSize += strlen(SUBECT_HEADER) + subject.Length() + 1;
|
||||
|
||||
if (dateStr)
|
||||
headersSize += strlen(DATE_HEADER) + strlen(dateStr) + 1;
|
||||
|
||||
if (headersSize) {
|
||||
char *headers = (char *)PR_Malloc(headersSize);
|
||||
char *headerPos = headers;
|
||||
if (!headers)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (authorStr) {
|
||||
PL_strcpy(headerPos, FROM_HEADER);
|
||||
headerPos += strlen(FROM_HEADER);
|
||||
|
||||
PL_strcpy(headerPos, authorStr);
|
||||
headerPos += strlen(authorStr);
|
||||
|
||||
*headerPos = '\0';
|
||||
headerPos++;
|
||||
}
|
||||
|
||||
if (!(subject.IsEmpty())) {
|
||||
PL_strcpy(headerPos, SUBECT_HEADER);
|
||||
headerPos += strlen(SUBECT_HEADER);
|
||||
|
||||
PL_strcpy(headerPos, subject.get());
|
||||
headerPos += subject.Length();
|
||||
|
||||
*headerPos = '\0';
|
||||
headerPos++;
|
||||
}
|
||||
|
||||
if (dateStr) {
|
||||
PL_strcpy(headerPos, DATE_HEADER);
|
||||
headerPos += strlen(DATE_HEADER);
|
||||
|
||||
PL_strcpy(headerPos, dateStr);
|
||||
headerPos += strlen(dateStr);
|
||||
|
||||
*headerPos = '\0';
|
||||
headerPos++;
|
||||
}
|
||||
|
||||
// on a filter hit (see ApplyFilterHit()), we'll be modifying the header
|
||||
// so keep track of the header
|
||||
m_newMsgHdr = newMsgHdr;
|
||||
|
||||
// the per-newsgroup filters should probably go first. It doesn't matter
|
||||
// right now since nothing stops filter execution for newsgroups, but if something
|
||||
// does, like adding a "stop execution" action, then users should be able to
|
||||
// override the global filters in the per-newsgroup filters.
|
||||
if (filterCount)
|
||||
{
|
||||
rv = m_filterList->ApplyFiltersToHdr(nsMsgFilterType::NewsRule, newMsgHdr, folder, m_newsDB,
|
||||
headers, headersSize, this, m_msgWindow, nsnull);
|
||||
}
|
||||
if (serverFilterCount)
|
||||
{
|
||||
rv = m_serverFilterList->ApplyFiltersToHdr(nsMsgFilterType::NewsRule, newMsgHdr, folder, m_newsDB,
|
||||
headers, headersSize, this, m_msgWindow, nsnull);
|
||||
}
|
||||
|
||||
PR_Free ((void*) headers);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
}
|
||||
|
||||
// if we deleted it, don't add it
|
||||
if (m_addHdrToDB) {
|
||||
rv = m_newsDB->AddNewHdrToDB(newMsgHdr, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNNTPNewsgroupList::ApplyFilterHit(nsIMsgFilter *aFilter, nsIMsgWindow *aMsgWindow, PRBool *aApplyMore)
|
||||
@@ -829,13 +929,48 @@ nsNNTPNewsgroupList::ProcessXOVERLINE(const char *line, PRUint32 *status)
|
||||
PRInt32 numDownloaded = lastIndex;
|
||||
PRInt32 totIndex = m_lastMsgNumber - m_firstMsgNumber + 1;
|
||||
|
||||
PRInt32 percent = (totIndex) ? (PRInt32)(100.0 * (double)numDownloaded / (double)totalToDownload) : 0;
|
||||
|
||||
PRTime elapsedTime;
|
||||
|
||||
LL_SUB(elapsedTime, PR_Now(), m_lastStatusUpdate);
|
||||
|
||||
if (LL_CMP(elapsedTime, >, MIN_STATUS_UPDATE_INTERVAL) ||
|
||||
lastIndex == totIndex)
|
||||
UpdateStatus(PR_FALSE, numDownloaded, totalToDownload);
|
||||
{
|
||||
nsAutoString numDownloadedStr;
|
||||
numDownloadedStr.AppendInt(numDownloaded);
|
||||
|
||||
nsAutoString totalToDownloadStr;
|
||||
totalToDownloadStr.AppendInt(totalToDownload);
|
||||
|
||||
nsString statusString;
|
||||
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
const PRUnichar *formatStrings[2] = { numDownloadedStr.get(), totalToDownloadStr.get() };
|
||||
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("downloadingHeaders").get(), formatStrings, 2, getter_Copies(statusString));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef DEBUG_NEWS
|
||||
PRInt32 elapsed;
|
||||
LL_L2I(elapsed, elapsedTime);
|
||||
printf("usecs elapsed since last update: %d\n", elapsed);
|
||||
#endif
|
||||
|
||||
SetProgressStatus(statusString.get());
|
||||
m_lastStatusUpdate = PR_Now();
|
||||
|
||||
// only update the progress meter if it has changed
|
||||
if (percent != m_lastPercent) {
|
||||
SetProgressBarPercent(percent);
|
||||
m_lastPercent = percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -848,6 +983,22 @@ nsNNTPNewsgroupList::ResetXOVER()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* When we don't have XOVER, but use HEAD, this is called instead.
|
||||
It reads lines until it has a whole header block, then parses the
|
||||
headers; then takes selected headers and creates an XOVER line
|
||||
from them. This is more for simplicity and code sharing than
|
||||
anything else; it means we end up parsing some things twice.
|
||||
But if we don't have XOVER, things are going to be so horribly
|
||||
slow anyway that this just doesn't matter.
|
||||
*/
|
||||
|
||||
nsresult
|
||||
nsNNTPNewsgroupList::ProcessNonXOVER (const char * /*line*/)
|
||||
{
|
||||
// ### dmb write me
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNNTPNewsgroupList::FinishXOVERLINE(int status, int *newstatus)
|
||||
{
|
||||
@@ -923,282 +1074,6 @@ nsNNTPNewsgroupList::ClearXOVERState()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPNewsgroupList::InitXHDR(nsACString &header)
|
||||
{
|
||||
++m_currentXHDRIndex;
|
||||
if (m_currentXHDRIndex >= m_filterHeaders.Count())
|
||||
header.Truncate();
|
||||
else
|
||||
header.Assign(*m_filterHeaders[m_currentXHDRIndex]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPNewsgroupList::ProcessXHDRLine(const nsACString &line)
|
||||
{
|
||||
PRInt32 middle = line.FindChar(' ');
|
||||
nsCString value, key = PromiseFlatCString(line);
|
||||
if (middle == kNotFound)
|
||||
return NS_OK;
|
||||
value = Substring(line, middle+1);
|
||||
key.Truncate((PRUint32)middle);
|
||||
|
||||
// According to RFC 2980, some will send (none) instead.
|
||||
// So we don't treat this is an error.
|
||||
if (key.CharAt(0) < '0' || key.CharAt(0) > '9')
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 code;
|
||||
PRInt32 number = key.ToInteger(&code);
|
||||
if (code != NS_OK)
|
||||
return NS_ERROR_FAILURE;
|
||||
// RFC 2980 specifies one or more spaces.
|
||||
value.Trim(" ");
|
||||
|
||||
nsCOMPtr <nsIMsgDBHdr> header;
|
||||
nsresult rv = m_newsDB->GetMsgHdrForKey(number, getter_AddRefs(header));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = header->SetStringProperty(m_filterHeaders[m_currentXHDRIndex]->get(), value.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 totalToDownload = m_lastMsgToDownload - m_firstMsgToDownload + 1;
|
||||
PRInt32 numDownloaded = number - m_firstMsgNumber + 1;
|
||||
|
||||
PRTime elapsedTime;
|
||||
|
||||
LL_SUB(elapsedTime, PR_Now(), m_lastStatusUpdate);
|
||||
|
||||
if (elapsedTime > MIN_STATUS_UPDATE_INTERVAL)
|
||||
UpdateStatus(PR_TRUE, numDownloaded, totalToDownload);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPNewsgroupList::InitHEAD(PRInt32 number)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (m_newMsgHdr)
|
||||
{
|
||||
// Finish processing for this header
|
||||
// If HEAD didn't properly return, then the header won't be set
|
||||
if (m_addHdrToDB)
|
||||
{
|
||||
rv = m_newsDB->AddNewHdrToDB(m_newMsgHdr, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
PRInt32 totalToDownload = m_lastMsgToDownload - m_firstMsgToDownload + 1;
|
||||
PRInt32 lastIndex = m_lastProcessedNumber - m_firstMsgNumber + 1;
|
||||
PRInt32 numDownloaded = lastIndex;
|
||||
PRInt32 totIndex = m_lastMsgNumber - m_firstMsgNumber + 1;
|
||||
|
||||
PRTime elapsedTime;
|
||||
|
||||
LL_SUB(elapsedTime, PR_Now(), m_lastStatusUpdate);
|
||||
|
||||
if (LL_CMP(elapsedTime, >, MIN_STATUS_UPDATE_INTERVAL) ||
|
||||
lastIndex == totIndex)
|
||||
UpdateStatus(PR_FALSE, numDownloaded, totalToDownload);
|
||||
}
|
||||
|
||||
if (number >= 0)
|
||||
{
|
||||
rv = m_newsDB->CreateNewHdr(number, getter_AddRefs(m_newMsgHdr));
|
||||
m_addHdrToDB = PR_FALSE;
|
||||
m_lastProcessedNumber = number;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNNTPNewsgroupList::ProcessHEADLine(const nsACString &line)
|
||||
{
|
||||
PRInt32 colon = line.FindChar(':');
|
||||
nsCString header = PromiseFlatCString(line), value;
|
||||
if (colon != kNotFound)
|
||||
{
|
||||
value = Substring(line, colon+1);
|
||||
header.Truncate((PRUint32)colon);
|
||||
}
|
||||
else if (line.CharAt(0) == ' ' || line.CharAt(0) == '\t') // We are continuing the header
|
||||
{
|
||||
m_thisLine += header; // Preserve whitespace (should we?)
|
||||
return NS_OK;
|
||||
}
|
||||
else
|
||||
return NS_OK; // We are malformed. Just ignore and hope for the best...
|
||||
|
||||
nsresult rv;
|
||||
if (!m_lastHeader.IsEmpty())
|
||||
{
|
||||
rv = AddHeader(m_lastHeader.get(), m_thisLine.get());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
value.Trim(" ");
|
||||
|
||||
ToLowerCase(header, m_lastHeader);
|
||||
m_thisLine.Assign(value);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNNTPNewsgroupList::AddHeader(const char *header, const char *value)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// The From, Date, and Subject headers have special requirements.
|
||||
if (PL_strcmp(header, "from") == 0)
|
||||
rv = m_newMsgHdr->SetAuthor(value);
|
||||
else if (PL_strcmp(header, "date") == 0)
|
||||
{
|
||||
PRTime date;
|
||||
PRStatus status = PR_ParseTimeString (value, PR_FALSE, &date);
|
||||
if (PR_SUCCESS == status)
|
||||
rv = m_newMsgHdr->SetDate(date);
|
||||
}
|
||||
else if (PL_strcmp(header, "subject") == 0)
|
||||
{
|
||||
const char *subject = value;
|
||||
PRUint32 subjectLen = strlen(value);
|
||||
|
||||
PRUint32 flags = 0;
|
||||
// ### should call IsHeaderRead here...
|
||||
/* strip "Re: " */
|
||||
nsCString modifiedSubject;
|
||||
if (NS_MsgStripRE(&subject, &subjectLen, getter_Copies(modifiedSubject)))
|
||||
// this will make sure read flags agree with newsrc
|
||||
(void) m_newMsgHdr->OrFlags(MSG_FLAG_HAS_RE, &flags);
|
||||
|
||||
if (! (flags & MSG_FLAG_READ))
|
||||
rv = m_newMsgHdr->OrFlags(MSG_FLAG_NEW, &flags);
|
||||
|
||||
rv = m_newMsgHdr->SetSubject(modifiedSubject.IsEmpty() ? subject :
|
||||
modifiedSubject.get());
|
||||
}
|
||||
else if (PL_strcmp(header, "message-id") == 0)
|
||||
{
|
||||
char * strippedId = PL_strdup(value);
|
||||
char * freeable = strippedId;
|
||||
if (strippedId[0] == '<')
|
||||
strippedId++;
|
||||
char * lastChar = strippedId + PL_strlen(strippedId) - 1;
|
||||
|
||||
if (*lastChar == '>')
|
||||
*lastChar = '\0';
|
||||
|
||||
rv = m_newMsgHdr->SetMessageId(strippedId);
|
||||
PL_strfree(freeable);
|
||||
}
|
||||
else if (PL_strcmp(header, "references") == 0)
|
||||
rv = m_newMsgHdr->SetReferences(value);
|
||||
else if (PL_strcmp(header, "bytes") == 0)
|
||||
rv = m_newMsgHdr->SetMessageSize(atol(value));
|
||||
else if (PL_strcmp(header, "lines") == 0)
|
||||
rv = m_newMsgHdr->SetLineCount(atol(value));
|
||||
else if (m_filterHeaders.IndexOf(nsDependentCString(header)) != -1)
|
||||
rv = m_newMsgHdr->SetStringProperty(header, value);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNNTPNewsgroupList::CallFilters()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCString filterString;
|
||||
|
||||
nsCOMPtr <nsIMsgFolder> folder = do_QueryInterface(m_newsFolder, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
PRUint32 filterCount = 0;
|
||||
if (m_filterList)
|
||||
{
|
||||
rv = m_filterList->GetFilterCount(&filterCount);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
PRUint32 serverFilterCount = 0;
|
||||
if (m_serverFilterList)
|
||||
{
|
||||
rv = m_serverFilterList->GetFilterCount(&serverFilterCount);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
if (filterCount == 0 && serverFilterCount == 0)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 count = 0;
|
||||
PRUint32 *keys;
|
||||
rv = m_newsDB->GetNewList(&count, &keys);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
for (PRUint32 i = 0; i<count; i++)
|
||||
{
|
||||
m_addHdrToDB = PR_TRUE;
|
||||
rv = m_newsDB->GetMsgHdrForKey(*keys++, getter_AddRefs(m_newMsgHdr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// build up a "headers" for filter code
|
||||
nsCString subject, author, date;
|
||||
rv = m_newMsgHdr->GetSubject(getter_Copies(subject));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = m_newMsgHdr->GetAuthor(getter_Copies(author));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCString fullHeaders;
|
||||
if (!(author.IsEmpty()))
|
||||
{
|
||||
fullHeaders.AppendLiteral(FROM_HEADER);
|
||||
fullHeaders += author;
|
||||
fullHeaders += '\0';
|
||||
}
|
||||
|
||||
if (!(subject.IsEmpty()))
|
||||
{
|
||||
fullHeaders.AppendLiteral(SUBJECT_HEADER);
|
||||
fullHeaders += subject;
|
||||
fullHeaders += '\0';
|
||||
}
|
||||
|
||||
for (PRInt32 header = 0; header < m_filterHeaders.Count(); header++)
|
||||
{
|
||||
char *retValue;
|
||||
m_newMsgHdr->GetStringProperty(m_filterHeaders[header]->get(), &retValue);
|
||||
if (*retValue)
|
||||
{
|
||||
fullHeaders += *(m_filterHeaders[header]);
|
||||
fullHeaders.AppendLiteral(": ");
|
||||
fullHeaders += nsCString(retValue);
|
||||
fullHeaders += '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// the per-newsgroup filters should probably go first. It doesn't matter
|
||||
// right now since nothing stops filter execution for newsgroups, but if something
|
||||
// does, like adding a "stop execution" action, then users should be able to
|
||||
// override the global filters in the per-newsgroup filters.
|
||||
if (filterCount)
|
||||
{
|
||||
rv = m_filterList->ApplyFiltersToHdr(nsMsgFilterType::NewsRule, m_newMsgHdr, folder, m_newsDB,
|
||||
fullHeaders.get(), fullHeaders.Length(), this, m_msgWindow, nsnull);
|
||||
}
|
||||
if (serverFilterCount)
|
||||
{
|
||||
rv = m_serverFilterList->ApplyFiltersToHdr(nsMsgFilterType::NewsRule, m_newMsgHdr, folder, m_newsDB,
|
||||
fullHeaders.get(), fullHeaders.Length(), this, m_msgWindow, nsnull);
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (!m_addHdrToDB)
|
||||
m_newsDB->DeleteHeader(m_newMsgHdr, nsnull, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsNNTPNewsgroupList::SetProgressBarPercent(PRInt32 percent)
|
||||
{
|
||||
@@ -1233,59 +1108,6 @@ nsNNTPNewsgroupList::SetProgressStatus(const PRUnichar *message)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsNNTPNewsgroupList::UpdateStatus(PRBool filtering, PRInt32 numDLed, PRInt32 totToDL)
|
||||
{
|
||||
double ratio = filtering ? (m_currentXHDRIndex+1.0)/(m_filterHeaders.Count()+1)
|
||||
: 1.0/(m_filterHeaders.Count()+1);
|
||||
PRInt32 percent = (PRInt32)(ratio * numDLed / totToDL);
|
||||
|
||||
nsAutoString numDownloadedStr;
|
||||
numDownloadedStr.AppendInt(numDLed);
|
||||
|
||||
nsAutoString totalToDownloadStr;
|
||||
totalToDownloadStr.AppendInt(totToDL);
|
||||
|
||||
nsresult rv;
|
||||
nsString statusString;
|
||||
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
if (!NS_SUCCEEDED(rv))
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
|
||||
if (!NS_SUCCEEDED(rv))
|
||||
return;
|
||||
|
||||
if (filtering)
|
||||
{
|
||||
NS_ConvertUTF8toUTF16 header(*m_filterHeaders[m_currentXHDRIndex]);
|
||||
const PRUnichar *formatStrings[3] = { header.get(),
|
||||
numDownloadedStr.get(), totalToDownloadStr.get() };
|
||||
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("downloadingFilterHeaders").get(),
|
||||
formatStrings, 3, getter_Copies(statusString));
|
||||
}
|
||||
else
|
||||
{
|
||||
const PRUnichar *formatStrings[2] = { numDownloadedStr.get(),
|
||||
totalToDownloadStr.get() };
|
||||
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("downloadingHeaders").get(),
|
||||
formatStrings, 2, getter_Copies(statusString));
|
||||
}
|
||||
if (!NS_SUCCEEDED(rv))
|
||||
return;
|
||||
|
||||
SetProgressStatus(statusString.get());
|
||||
m_lastStatusUpdate = PR_Now();
|
||||
|
||||
// only update the progress meter if it has changed
|
||||
if (percent != m_lastPercent)
|
||||
{
|
||||
SetProgressBarPercent(percent);
|
||||
m_lastPercent = percent;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNNTPNewsgroupList::SetGetOldMessages(PRBool aGetOldMessages)
|
||||
{
|
||||
m_getOldMessages = aGetOldMessages;
|
||||
|
||||
@@ -103,9 +103,6 @@ private:
|
||||
void SetProgressBarPercent(PRInt32 percent);
|
||||
void SetProgressStatus(const PRUnichar *message);
|
||||
|
||||
void UpdateStatus(PRBool filtering, PRInt32 numDled, PRInt32 totToDL);
|
||||
|
||||
nsresult AddHeader(const char * header, const char * value);
|
||||
protected:
|
||||
PRBool m_getOldMessages;
|
||||
PRBool m_promptedAlready;
|
||||
@@ -127,19 +124,12 @@ protected:
|
||||
struct MSG_NewsKnown m_knownArts;
|
||||
nsMsgKeySet *m_set;
|
||||
|
||||
nsCStringArray m_filterHeaders;
|
||||
PRInt32 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 */
|
||||
|
||||
PRBool m_addHdrToDB;
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsNNTPNewsgroupListState_h___ */
|
||||
|
||||
@@ -97,8 +97,6 @@
|
||||
#include "nsIMsgNewsFolder.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
#include "nsIMsgFilterList.h"
|
||||
|
||||
// for the memory cache...
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsICacheSession.h"
|
||||
@@ -204,9 +202,6 @@ const char *const stateLabels[] = {
|
||||
"NNTP_XOVER_RESPONSE",
|
||||
"NNTP_XOVER",
|
||||
"NEWS_PROCESS_XOVER",
|
||||
"NNTP_XHDR_SEND",
|
||||
"NNTP_XHDR_RESPONSE",
|
||||
"NNTP_XHDR",
|
||||
"NNTP_READ_GROUP",
|
||||
"NNTP_READ_GROUP_RESPONSE",
|
||||
"NNTP_READ_GROUP_BODY",
|
||||
@@ -3295,11 +3290,8 @@ void nsNNTPProtocol::HandleAuthenticationFailure()
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// XOVER, XHDR, and HEAD processing code
|
||||
// Used for filters
|
||||
// State machine explanation located in doxygen comments for nsNNTPProtocol
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/* start the xover command
|
||||
*/
|
||||
|
||||
PRInt32 nsNNTPProtocol::BeginReadXover()
|
||||
{
|
||||
@@ -3383,7 +3375,8 @@ PRInt32 nsNNTPProtocol::FigureNextChunk()
|
||||
rv = m_newsgroupList->GetRangeOfArtsToDownload(m_msgWindow,
|
||||
m_firstPossibleArticle,
|
||||
m_lastPossibleArticle,
|
||||
m_numArticlesWanted - m_numArticlesLoaded,
|
||||
m_numArticlesWanted -
|
||||
m_numArticlesLoaded,
|
||||
&(m_firstArticle),
|
||||
&(m_lastArticle),
|
||||
&status);
|
||||
@@ -3504,7 +3497,7 @@ PRInt32 nsNNTPProtocol::ReadXover(nsIInputStream * inputStream, PRUint32 length)
|
||||
|
||||
if(line[0] == '.' && line[1] == '\0')
|
||||
{
|
||||
m_nextState = NNTP_XHDR_SEND;
|
||||
m_nextState = NNTP_FIGURE_NEXT_CHUNK;
|
||||
ClearFlag(NNTP_PAUSE_FOR_READ);
|
||||
PR_Free(lineToFree);
|
||||
return(0);
|
||||
@@ -3526,7 +3519,7 @@ PRInt32 nsNNTPProtocol::ReadXover(nsIInputStream * inputStream, PRUint32 length)
|
||||
|
||||
m_numArticlesLoaded++;
|
||||
PR_Free(lineToFree);
|
||||
return NS_SUCCEEDED(rv) ? (PRInt32)status : -1; /* keep going if no error */
|
||||
return NS_SUCCEEDED(rv) ? status : -1; /* keep going if no error */
|
||||
}
|
||||
|
||||
/* Finished processing all the XOVER data.
|
||||
@@ -3541,7 +3534,6 @@ PRInt32 nsNNTPProtocol::ProcessXover()
|
||||
if (!m_newsgroupList) return -1;
|
||||
|
||||
PRInt32 status = 0;
|
||||
m_newsgroupList->CallFilters();
|
||||
rv = m_newsgroupList->FinishXOVERLINE(0,&status);
|
||||
m_newsgroupList = nsnull;
|
||||
if (NS_SUCCEEDED(rv) && status < 0) return status;
|
||||
@@ -3551,113 +3543,17 @@ PRInt32 nsNNTPProtocol::ProcessXover()
|
||||
return(MK_DATA_LOADED);
|
||||
}
|
||||
|
||||
PRInt32 nsNNTPProtocol::XhdrSend()
|
||||
{
|
||||
nsCString header;
|
||||
m_newsgroupList->InitXHDR(header);
|
||||
if (header.IsEmpty())
|
||||
{
|
||||
m_nextState = NNTP_FIGURE_NEXT_CHUNK;
|
||||
return 0;
|
||||
}
|
||||
char outputBuffer[OUTPUT_BUFFER_SIZE];
|
||||
PRInt32 status = 0;
|
||||
|
||||
PR_snprintf(outputBuffer, OUTPUT_BUFFER_SIZE,
|
||||
"XHDR %s %d-%d" CRLF,
|
||||
header.get(), m_firstArticle, m_lastArticle);
|
||||
NNTP_LOG_WRITE(outputBuffer);
|
||||
|
||||
m_nextState = NNTP_RESPONSE;
|
||||
m_nextStateAfterResponse = NNTP_XHDR_RESPONSE;
|
||||
SetFlag(NNTP_PAUSE_FOR_READ);
|
||||
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(m_runningURL);
|
||||
if (mailnewsurl)
|
||||
status = SendData(mailnewsurl, outputBuffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
PRInt32 nsNNTPProtocol::ReadXhdrResponse()
|
||||
{
|
||||
#ifdef TEST_NO_XOVER_SUPPORT
|
||||
m_responseCode = MK_NNTP_RESPONSE_CHECK_ERROR; /* pretend XHDR generated an error */
|
||||
#endif
|
||||
|
||||
if(m_responseCode != MK_NNTP_RESPONSE_XHDR_OK)
|
||||
{
|
||||
m_nextState = NNTP_READ_GROUP;
|
||||
// The reasoning behind setting this flag and not an XHDR flag is that we
|
||||
// are going to have to use HEAD instead. At that point, using XOVER as
|
||||
// well is just wasting bandwidth.
|
||||
SetFlag(NNTP_NO_XOVER_SUPPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nextState = NNTP_XHDR;
|
||||
}
|
||||
|
||||
return(0); /* continue */
|
||||
}
|
||||
|
||||
PRInt32 nsNNTPProtocol::ReadXhdr(nsIInputStream * inputStream, PRUint32 length)
|
||||
{
|
||||
char *line, *lineToFree;
|
||||
nsresult rv;
|
||||
PRUint32 status = 1;
|
||||
|
||||
PRBool pauseForMoreData = PR_FALSE;
|
||||
line = lineToFree = m_lineStreamBuffer->ReadNextLine(inputStream, status, pauseForMoreData);
|
||||
|
||||
if(pauseForMoreData)
|
||||
{
|
||||
SetFlag(NNTP_PAUSE_FOR_READ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!line)
|
||||
return(status); /* no line yet or TCP error */
|
||||
|
||||
if(line[0] == '.' && line[1] == '\0')
|
||||
{
|
||||
m_nextState = NNTP_XHDR_SEND;
|
||||
ClearFlag(NNTP_PAUSE_FOR_READ);
|
||||
PR_Free(lineToFree);
|
||||
return(0);
|
||||
}
|
||||
else if (line [0] == '.' && line [1] == '.')
|
||||
/* The NNTP server quotes all lines beginning with "." by doubling it. */
|
||||
line++;
|
||||
|
||||
if(status > 1)
|
||||
{
|
||||
mBytesReceived += status;
|
||||
mBytesReceivedSinceLastStatusUpdate += status;
|
||||
}
|
||||
|
||||
rv = m_newsgroupList->ProcessXHDRLine(nsCString(line));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to process the XHDRLINE");
|
||||
|
||||
m_numArticlesLoaded++;
|
||||
PR_Free(lineToFree);
|
||||
return NS_SUCCEEDED(rv) ? (PRInt32)status : -1; /* keep going if no error */
|
||||
}
|
||||
|
||||
PRInt32 nsNNTPProtocol::ReadNewsgroup()
|
||||
{
|
||||
if(m_articleNumber > m_lastArticle)
|
||||
{ /* end of groups */
|
||||
|
||||
m_newsgroupList->InitHEAD(-1);
|
||||
m_nextState = NNTP_FIGURE_NEXT_CHUNK;
|
||||
ClearFlag(NNTP_PAUSE_FOR_READ);
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_newsgroupList->InitHEAD(m_articleNumber);
|
||||
|
||||
char outputBuffer[OUTPUT_BUFFER_SIZE];
|
||||
PR_snprintf(outputBuffer,
|
||||
OUTPUT_BUFFER_SIZE,
|
||||
@@ -3691,7 +3587,10 @@ PRInt32 nsNNTPProtocol::ReadNewsgroupResponse()
|
||||
|
||||
m_key = nsMsgKey_None;
|
||||
|
||||
return 0;
|
||||
/* Give the message number to the header parser. */
|
||||
rv = m_newsgroupList->ProcessNonXOVER(m_responseText);
|
||||
/* convert nsresult->status */
|
||||
return NS_FAILED(rv);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3730,16 +3629,14 @@ PRInt32 nsNNTPProtocol::ReadNewsgroupBody(nsIInputStream * inputStream, PRUint32
|
||||
{
|
||||
m_nextState = NNTP_READ_GROUP;
|
||||
ClearFlag(NNTP_PAUSE_FOR_READ);
|
||||
return 0;
|
||||
}
|
||||
else if (line [0] == '.' && line [1] == '.')
|
||||
/* The NNTP server quotes all lines beginning with "." by doubling it. */
|
||||
line++;
|
||||
|
||||
nsCString safe_line(line);
|
||||
rv = m_newsgroupList->ProcessHEADLine(safe_line);
|
||||
PR_Free(lineToFree);
|
||||
rv = m_newsgroupList->ProcessNonXOVER(line);
|
||||
/* convert nsresult->status */
|
||||
PR_Free(lineToFree);
|
||||
return NS_FAILED(rv);
|
||||
}
|
||||
|
||||
@@ -5135,18 +5032,6 @@ nsresult nsNNTPProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
||||
status = ProcessXover();
|
||||
break;
|
||||
|
||||
case NNTP_XHDR_SEND:
|
||||
status = XhdrSend();
|
||||
break;
|
||||
|
||||
case NNTP_XHDR_RESPONSE:
|
||||
status = ReadXhdrResponse();
|
||||
break;
|
||||
|
||||
case NNTP_XHDR:
|
||||
status = ReadXhdr(inputStream, length);
|
||||
break;
|
||||
|
||||
case NNTP_READ_GROUP:
|
||||
status = ReadNewsgroup();
|
||||
break;
|
||||
@@ -5159,7 +5044,7 @@ nsresult nsNNTPProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
||||
break;
|
||||
|
||||
case NNTP_READ_GROUP_BODY:
|
||||
status = ReadNewsgroupBody(inputStream, length);
|
||||
status = ReadNewsgroupResponse();
|
||||
break;
|
||||
|
||||
case NNTP_SEND_POST_DATA:
|
||||
|
||||
@@ -118,9 +118,6 @@ NNTP_XOVER_SEND,
|
||||
NNTP_XOVER_RESPONSE,
|
||||
NNTP_XOVER,
|
||||
NEWS_PROCESS_XOVER,
|
||||
NNTP_XHDR_SEND,
|
||||
NNTP_XHDR_RESPONSE,
|
||||
NNTP_XHDR,
|
||||
NNTP_READ_GROUP,
|
||||
NNTP_READ_GROUP_RESPONSE,
|
||||
NNTP_READ_GROUP_BODY,
|
||||
@@ -273,6 +270,7 @@ private:
|
||||
|
||||
PRInt32 m_originalContentLength; /* the content length at the time of calling graph progress */
|
||||
|
||||
|
||||
nsCOMPtr<nsIStringBundle> m_stringBundle;
|
||||
|
||||
nsCOMPtr<nsINntpIncomingServer> m_nntpServer;
|
||||
@@ -350,6 +348,11 @@ private:
|
||||
PRInt32 BeginNewsgroups();
|
||||
PRInt32 ProcessNewsgroups(nsIInputStream * inputStream, PRUint32 length);
|
||||
|
||||
PRInt32 ReadNewsgroup();
|
||||
PRInt32 ReadNewsgroupResponse();
|
||||
|
||||
PRInt32 ReadNewsgroupBody(nsIInputStream * inputStream, PRUint32 length);
|
||||
|
||||
// Protocol handlers used for posting data
|
||||
PRInt32 PostData();
|
||||
PRInt32 PostDataResponse();
|
||||
@@ -360,105 +363,19 @@ private:
|
||||
PRInt32 DisplayNewsRC();
|
||||
PRInt32 DisplayNewsRCResponse();
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
*/
|
||||
// start off the xover command
|
||||
PRInt32 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
|
||||
*/
|
||||
PRInt32 FigureNextChunk();
|
||||
|
||||
// The XOVER process core
|
||||
/**
|
||||
* The state NNTP_XOVER_SEND, which actually sends the message.
|
||||
* Followed by: NNTP_XOVER_RESPONSE
|
||||
*/
|
||||
PRInt32 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
|
||||
*/
|
||||
PRInt32 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
|
||||
*/
|
||||
// process the xover list as it comes from the server and load it into the sort list.
|
||||
PRInt32 ReadXover(nsIInputStream * inputStream, PRUint32 length);
|
||||
// See if the xover response is going to return us data. If the proper code isn't returned then
|
||||
// assume xover isn't supported and use normal read_group.
|
||||
PRInt32 ReadXoverResponse();
|
||||
|
||||
// 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
|
||||
*/
|
||||
PRInt32 XhdrSend();
|
||||
/**
|
||||
* This state, NNTP_XHDR_RESPONSE, evaluates the response.
|
||||
* Note that if XHDR doesn't work properly, HEAD fallback is switched on and
|
||||
* all subsequent chunks will NOT use XOVER.
|
||||
* Followed by: NNTP_XHDR if XHDR works properly
|
||||
* NNTP_READ_GROUP if it doesn't
|
||||
*/
|
||||
PRInt32 ReadXhdrResponse();
|
||||
/**
|
||||
* This state, NNTP_XHDR, processes each line of the XHDR response.
|
||||
* It mostly passes everything off to nsNNTPNewsgroupList and only checks for
|
||||
* the end of the response and various other preprocessing.
|
||||
* Followed by: NNTP_XHDR_SEND
|
||||
*/
|
||||
PRInt32 ReadXhdr(nsIInputStream * inputStream, PRUint32 length);
|
||||
|
||||
// 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
|
||||
*/
|
||||
PRInt32 ReadNewsgroup();
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
PRInt32 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
|
||||
*/
|
||||
PRInt32 ReadNewsgroupBody(nsIInputStream * inputStream, PRUint32 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
|
||||
*/
|
||||
PRInt32 XoverSend();
|
||||
PRInt32 ProcessXover();
|
||||
|
||||
|
||||
PRInt32 FigureNextChunk();
|
||||
|
||||
// Canceling
|
||||
PRInt32 StartCancel();
|
||||
|
||||
@@ -52,9 +52,7 @@ enterPasswordTitle=News Server Password Required
|
||||
okButtonText=Download
|
||||
|
||||
noNewMessages=There are no new messages on the server.
|
||||
# The difference between these two is that the second one is shown when processing XHDR commands
|
||||
downloadingHeaders=Downloading %S of %S headers
|
||||
downloadingFilterHeaders=Getting filter headers: %S (%S/%S)
|
||||
downloadingArticles=Downloading articles %S-%S
|
||||
bytesReceived=Downloading newsgroups: %S received (%SKB read at %SKB/sec)
|
||||
checkingForNewNews=Checking newsgroup %S of %S on %S for new messages
|
||||
|
||||
Reference in New Issue
Block a user