diff options
Diffstat (limited to 'src/operator-select.cc')
-rw-r--r-- | src/operator-select.cc | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/operator-select.cc b/src/operator-select.cc new file mode 100644 index 0000000..854783a --- /dev/null +++ b/src/operator-select.cc @@ -0,0 +1,158 @@ +/** -------------------------------------------------------------------- + * @file operator-select.cc + * @brief Implementation of the SELECT command. + * @author Andreas Aardal Hanssen + * @date 2002-2005 + * ----------------------------------------------------------------- **/ +#include <string> + +#include "depot.h" +#include "iodevice.h" +#include "iofactory.h" +#include "mailbox.h" +#include "operators.h" +#include "recursivedescent.h" +#include "pendingupdates.h" +#include "session.h" +#include "convert.h" + +using namespace ::std; +using namespace Binc; + +//---------------------------------------------------------------------- +SelectOperator::SelectOperator(void) +{ +} + +//---------------------------------------------------------------------- +SelectOperator::~SelectOperator(void) +{ +} + +//---------------------------------------------------------------------- +const string SelectOperator::getName(void) const +{ + return "SELECT"; +} + +//---------------------------------------------------------------------- +int SelectOperator::getState(void) const +{ + return Session::NONAUTHENTICATED + | Session::AUTHENTICATED + | Session::SELECTED; +} + +//------------------------------------------------------------------------ +Operator::ProcessResult SelectOperator::process(Depot &depot, + Request &command) +{ + Session &session = Session::getInstance(); + + const bool examine = (command.getName() == "EXAMINE"); + const string &srcmailbox = command.getMailbox(); + const string &canonmailbox = toCanonMailbox(srcmailbox); + + Mailbox *mailbox = depot.getSelected(); + if (mailbox != 0) { + mailbox->closeMailbox(); + depot.resetSelected(); + mailbox = 0; + } + + mailbox = depot.get(canonmailbox); + if (mailbox == 0) { + session.setLastError(depot.getLastError()); + return NO; + } + + mailbox->setReadOnly(examine); + + if (!mailbox->selectMailbox(canonmailbox, + depot.mailboxToFilename(canonmailbox))) { + bincWarning << "selecting mailbox failed: " + << mailbox->getLastError() << endl; + session.setLastError(mailbox->getLastError()); + return NO; + } + + // find first unseen + int unseen = -1; + Mailbox::iterator i = mailbox->begin(SequenceSet::all(), + Mailbox::SKIP_EXPUNGED | Mailbox::SQNR_MODE); + for (; i != mailbox->end(); ++i) { + Message &message = *i; + + if (unseen == -1 && ((message.getStdFlags() & Message::F_SEEN) == 0)) { + unseen = i.getSqnr(); + break; + } + } + + // show pending updates with only exists and recent response. do not + // re-scan. + pendingUpdates(mailbox, PendingUpdates::EXISTS + | PendingUpdates::RECENT, false, true); + + // unseen + if (unseen != -1) + bincClient << "*" << " OK [UNSEEN " << unseen << "] Message " + << unseen << " is first unseen" << endl; + + // uidvalidity + bincClient << "*" << " OK [UIDVALIDITY " << mailbox->getUidValidity() << "]" + << endl; + + // uidnext + bincClient << "*" << " OK [UIDNEXT " << toString(mailbox->getUidNext()) << "] " + << toString(mailbox->getUidNext()) << " is the next UID" << endl; + + // flags + bincClient << "*" + << " FLAGS (\\Answered \\Flagged \\Deleted \\Recent \\Seen \\Draft \\*)" + << endl; + + // permanentflags + bincClient << "*" + << " OK [PERMANENTFLAGS (\\Answered \\Flagged \\Deleted " + << "\\Seen \\Draft \\*)] Limited" + << endl; + + session.setState(Session::SELECTED); + depot.setSelected(mailbox); + + session.setResponseCode(examine ? "READ-ONLY" : "READ-WRITE"); + return OK; +} + +//---------------------------------------------------------------------- +Operator::ParseResult SelectOperator::parse(Request &c_in) const +{ + Session &session = Session::getInstance(); + + if (c_in.getUidMode()) + return REJECT; + + Operator::ParseResult res; + if ((res = expectSPACE()) != ACCEPT) { + session.setLastError("Expected SPACE after" + c_in.getName()); + return res; + } + + string mailbox; + if ((res = expectMailbox(mailbox)) != ACCEPT) { + session.setLastError("Expected mailbox after " + c_in.getName() + + " SPACE"); + return res; + } + + if ((res = expectCRLF()) != ACCEPT) { + session.setLastError("Expected CRLF after " + c_in.getName() + + " SPACE mailbox"); + return res; + } + + c_in.setMailbox(mailbox); + + return ACCEPT; +} |