diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 |
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /libmail/nntpgroupopen.C | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'libmail/nntpgroupopen.C')
| -rw-r--r-- | libmail/nntpgroupopen.C | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/libmail/nntpgroupopen.C b/libmail/nntpgroupopen.C new file mode 100644 index 0000000..70345bb --- /dev/null +++ b/libmail/nntpgroupopen.C @@ -0,0 +1,331 @@ +/* +** Copyright 2003, Double Precision Inc. +** +** See COPYING for distribution information. +*/ +#include "nntp.H" +#include "nntpgroupopen.H" +#include "nntpchecknew.H" +#include "nntpnewsrc.H" +#include <sstream> +#include <fstream> +#include <errno.h> +#include <cstring> + +using namespace std; + +///////////////////////////////////////////////////////////////////////////// +// +// Helper class for restoring application-saved snapshots + +mail::nntp::GroupOpenTask::snapshotRestoreHelper +::snapshotRestoreHelper(mail::nntp &nntpArg) + : orignntp(nntpArg), abortedFlag(false) +{ +} + +mail::nntp::GroupOpenTask::snapshotRestoreHelper::~snapshotRestoreHelper() +{ +} + +void mail::nntp::GroupOpenTask::snapshotRestoreHelper +::restoreIndex(size_t msgNum, + const mail::messageInfo &mi) +{ + if (msgNum >= index.size()) + return; + + istringstream i(mi.uid); + msgnum_t n=0; + + i >> n; + + if (i.fail() || n == 0) + return; + + index[msgNum].msgNum=n; + + unsigned char flags=0; + + if (mi.deleted) + flags |= IDX_DELETED; + + if (mi.marked) + flags |= IDX_FLAGGED; + + index[msgNum].msgFlag=flags; +} + +void mail::nntp::GroupOpenTask::snapshotRestoreHelper +::restoreKeywords(size_t msgNum, + const std::set<std::string> &kwSet) +{ + if (msgNum >= index.size()) + return; + + index[msgNum].keywords.setFlags(orignntp.keywordHashtable, kwSet); +} + +void mail::nntp::GroupOpenTask::snapshotRestoreHelper::abortRestore() +{ + abortedFlag=true; +} + +///////////////////////////////////////////////////////////////////////////// + +mail::nntp::GroupOpenTask::GroupOpenTask(callback *callbackArg, + nntp &myserverArg, + std::string groupNameArg, + snapshot *restoreSnapshotArg, + callback::folder *folderCallbackArg) + : GroupTask(callbackArg, myserverArg, groupNameArg), + folderCallback(folderCallbackArg), + groupName(groupNameArg), + restoreSnapshot(restoreSnapshotArg) +{ +} + +mail::nntp::GroupOpenTask::~GroupOpenTask() +{ +} + +void mail::nntp::GroupOpenTask::selectedGroup(msgnum_t estimatedCount, + msgnum_t loArticleCount, + msgnum_t hiArticleCount) +{ + myserver->openedGroup=""; + myserver->cleartmp(); + myserver->index.clear(); + myserver->index.reserve(estimatedCount); + myserver->loWatermark=loArticleCount; + myserver->hiWatermark=hiArticleCount; + + map<std::string, newsrc>::iterator p; + + if (myserver->didCacheNewsrc && + (p=myserver->cachedNewsrc.find(groupName)) != + myserver->cachedNewsrc.end()) + { + myNewsrc=p->second; + } + else + { + myNewsrc.newsgroupname=groupName; + myNewsrc.subscribed=false; + + ifstream i(myserver->newsrcFilename.c_str()); + + string line; + + while (i.is_open() && !getline(i, line).fail()) + { + newsrc parseLine(line); + + if (parseLine.newsgroupname == groupName) + { + myNewsrc=parseLine; + break; + } + } + } + + if (!myNewsrc.subscribed) // Subscribed now, clear deleted list. + { + myNewsrc.subscribed=true; + myNewsrc.msglist.clear(); + } + + if (myNewsrc.msglist.size() > 0 && + myNewsrc.msglist.end()[-1].second > hiArticleCount) + { + myNewsrc.msglist.clear(); // Group renumbered on the swerver + } + + msglistI=myNewsrc.msglist.begin(); + + string cmd="LISTGROUP\r\n"; + + if (restoreSnapshot) + { + size_t cnt; + string dummy; + msgnum_t cLo=0, cHi=0; + + restoreSnapshot->getSnapshotInfo(dummy, cnt); + + if (dummy.size() > 0) + { + istringstream iss(dummy); + + char dummyChar; + + iss >> cLo >> dummyChar >> cHi; + + if (iss.fail() || cLo == 0 || dummyChar != '-' || + cHi < cLo || + cHi > myserver->hiWatermark + // Server probably renumbered + ) + { + dummy=""; + } + } + + if (dummy.size() > 0) + { + snapshotRestoreHelper myHelper(*myserver); + + myHelper.index.resize(cnt); + + restoreSnapshot->restoreSnapshot(myHelper); + + if (!myHelper.abortedFlag) + { + // Sanity check + + vector<nntpMessageInfo>::iterator + b=myHelper.index.begin(), + e=myHelper.index.end(); + + bool first=true; + + while (b != e) + { + if (b->msgNum == 0 || + (!first && + b[-1].msgNum >= b->msgNum)) + { + myHelper.abortedFlag=true; + break; + } + b++; + first=false; + } + } + if (!myHelper.abortedFlag) + { + size_t i; + size_t n=myHelper.index.size(); + + for (i=0; i<n; i++) + { + if (myHelper.index[i].msgNum < + myserver->loWatermark) + continue; + + processMessageNumber(myHelper + .index[i].msgNum, + myHelper + .index[i].msgFlag, + myHelper + .index[i].keywords); + } + + ostringstream o; + + o << "XHDR Lines " << cHi << "-\r\n"; + cmd=o.str(); + } + } + } + + response_func= &mail::nntp::GroupOpenTask::processLISTGROUP; + myserver->socketWrite(cmd); +} + +void mail::nntp::GroupOpenTask::processGroup(const char *msg) +{ + (this->*response_func)(msg); +} + +void mail::nntp::GroupOpenTask::processLISTGROUP(const char *msg) +{ + if (msg[0] == '4') + { + response_func= + &mail::nntp::GroupOpenTask::processMessageNumber; + + processMessageNumber("."); + return; + } + + if (msg[0] != '2') + { + fail(msg); + return; + } + + response_func= &mail::nntp::GroupOpenTask::processMessageNumber; +} + + +bool mail::nntp::GroupOpenTask::opened() +{ + myserver->folderCallback=folderCallback; + myserver->openedGroup=groupName; + myserver->createNewsrc(myNewsrc); + + if (!myserver->updateOpenedNewsrc(myNewsrc)) + { + fail(strerror(errno)); + return false; + } + return true; +} + +void mail::nntp::GroupOpenTask::processMessageNumber(const char *msg) +{ + if (strcmp(msg, ".") == 0) + { + if (!opened()) + return; + myserver->saveSnapshot(); + + ostringstream o; + + o << groupName << ": " << myserver->index.size() + << " messages."; + + success(o.str()); + return; + } + + string s(msg); + istringstream i(s); + + msgnum_t n; + + i >> n; + + if (!i.bad() && !i.fail()) + { + mail::keywords::Message kw; + + processMessageNumber(n, 0, kw); + } +} + +void mail::nntp::GroupOpenTask::processMessageNumber(msgnum_t n, + unsigned char flags, + mail::keywords::Message + &kw) +{ + while (msglistI != myNewsrc.msglist.end() && + msglistI->second < n) + msglistI++; + + if (msglistI != myNewsrc.msglist.end() && + msglistI->first <= n) + return; // This message is excluded + + if (myserver->index.size() > 0 && + n <= myserver->index.end()[-1].msgNum) + return; // Bad server mojo + + nntpMessageInfo newInfo; + + newInfo.msgNum=n; + newInfo.msgFlag=flags; + newInfo.keywords=kw; + myserver->index.push_back(newInfo); +} |
