#include "__IMAP_STORE.h" #include "IMAPArgs.h" #include "IMAPServer.h" #include #include namespace mail { namespace { std::string joinFlags(const std::vector &flags) { std::string out; for (size_t i = 0; i < flags.size(); ++i) { if (i > 0) out += " "; out += flags[i]; } return out; } } int storeImpl(coreutils::ZString &request, IMAPSession &session, IMAPServer &server, bool uidMode) { if (session.state != IMAPSession::SELECTED) { session.out << session.tag << " NO No mailbox selected" << CRLF; return 1; } if (session.readOnly) { session.out << session.tag << " NO Mailbox is read-only" << CRLF; return 1; } std::vector uids = IMAPArgs::parseSequenceSet(request, session.mailbox, uidMode); coreutils::ZString modeArg = IMAPArgs::nextArgument(request); std::string mode = modeArg.str(); bool silent = false; // Strip a trailing ".SILENT" (case-insensitive) before inspecting // the leading +/- sign. if (mode.size() >= 7) { std::string tail = mode.substr(mode.size() - 7); for (char &c : tail) c = std::toupper((unsigned char)c); if (tail == ".SILENT") { silent = true; mode = mode.substr(0, mode.size() - 7); } } char sign = mode.empty() ? '=' : mode[0]; std::vector flags = IMAPArgs::parseFlagList(request); for (uint32_t uid : uids) { MailFolder::Message *message = session.mailbox.find(uid); if (!message) continue; if (sign == '+') session.mailbox.addFlags(uid, flags); else if (sign == '-') session.mailbox.removeFlags(uid, flags); else session.mailbox.setFlags(uid, flags); if (!silent) { uint32_t seqNum = session.mailbox.seq(uid); session.out << "* " << (int)seqNum << " FETCH (FLAGS (" << joinFlags(message->flags) << ")"; if (uidMode) session.out << " UID " << (int)uid; session.out << ")" << CRLF; } } session.out << session.tag << " OK " << (uidMode ? "UID STORE" : "STORE") << " completed" << CRLF; return 1; } int __IMAP_STORE::processCommand(coreutils::ZString &request, IMAPSession &session, IMAPServer &server) { return storeImpl(request, session, server, false); } }