Bincimap 2.0.16
Easy Imapping
Loading...
Searching...
No Matches
operator-copy.cc
Go to the documentation of this file.
1
7#include <string>
8
9#include "depot.h"
10#include "iodevice.h"
11#include "iofactory.h"
12#include "maildir.h"
13#include "operators.h"
14#include "recursivedescent.h"
15#include "session.h"
16#include "convert.h"
17
18using namespace ::std;
19using namespace Binc;
20
21//----------------------------------------------------------------------
23{
24}
25
26//----------------------------------------------------------------------
28{
29}
30
31//----------------------------------------------------------------------
32const string CopyOperator::getName(void) const
33{
34 return "COPY";
35}
36
37//----------------------------------------------------------------------
39{
40 return Session::SELECTED;
41}
42
43//------------------------------------------------------------------------
45 Request &command)
46{
47 Session &session = Session::getInstance();
48
49 // Get the current mailbox
50 Mailbox *srcMailbox = depot.getSelected();
51
52 // Get the destination mailbox
53 string dmailbox = command.getMailbox();
54 Mailbox *destMailbox = depot.get(toCanonMailbox(dmailbox));
55 if (destMailbox == 0) {
56 session.setResponseCode("TRYCREATE");
57 session.setLastError("invalid mailbox " + toImapString(dmailbox));
58 return NO;
59 }
60
61 unsigned int mode = Mailbox::SKIP_EXPUNGED;
63
64 // Copy each message in the sequence set to the destination mailbox.
65 bool success = true;
66 Mailbox::iterator i = srcMailbox->begin(command.bset, mode);
67 for (; success && i != srcMailbox->end(); ++i) {
68 Message &source = *i;
69
70 if (srcMailbox->fastCopy(source, *destMailbox,
71 depot.mailboxToFilename(toCanonMailbox(dmailbox))))
72 continue;
73
74 // Have the destination mailbox create a message for us.
75 Message *dest
76 = destMailbox->createMessage(depot.mailboxToFilename(toCanonMailbox(dmailbox)),
77 source.getInternalDate());
78 if (!dest) {
79 session.setLastError(destMailbox->getLastError());
80 success = false;
81 break;
82 }
83
84 // Set the flags and internal date.
85 dest->setStdFlag(source.getStdFlags());
86 dest->setInternalDate(source.getInternalDate());
87
88 // Copy chunks from the source message over to the destination
89 // message.
90 string chunk;
91 do {
92 int readSize = source.readChunk(chunk);
93
94 if (readSize == 0) break;
95 else if (readSize == -1) {
96 bincWarning << "when reading from message "
97 << i.getSqnr() << "/" << source.getUID()
98 << " in \"" << srcMailbox->getName() << "\": "
99 << source.getLastError() << endl;
100 success = false;
101 } else if (!dest->appendChunk(chunk)) {
102 bincWarning << "when writing to \""
103 << dmailbox << "\": "
104 << dest->getLastError() << endl;
105 success = false;
106 }
107 } while (success);
108
109 dest->close();
110 }
111
112 if (!success && !destMailbox->rollBackNewMessages()) {
113 session.setLastError("Failed to rollback after unsuccessful copy: "
114 + destMailbox->getLastError());
115 return NO;
116 }
117
118 if (success)
119 if (!destMailbox->commitNewMessages(depot.mailboxToFilename(toCanonMailbox(dmailbox)))) {
120 session.setLastError("Failed to commit after successful copy: "
121 + destMailbox->getLastError());
122 return NO;
123 }
124
125 if (!success)
126 session.setLastError("The transaction was unrolled. Please "
127 "contant your system administrator for "
128 "more information.");
129
130 return success ? OK : NO;
131}
132
133//------------------------------------------------------------------------
135{
136 Session &session = Session::getInstance();
137
139 if ((res = expectSPACE()) != ACCEPT) {
140 session.setLastError("Expected SPACE after COPY");
141 return res;
142 }
143
144 if ((res = expectSet(c_in.getSet())) != ACCEPT) {
145 session.setLastError("Expected sequence set after COPY SPACE");
146 return res;
147 }
148
149 if ((res = expectSPACE()) != ACCEPT) {
150 session.setLastError("Expected SPACE after COPY SPACE set");
151 return res;
152 }
153
154 string mailbox;
155 if ((res = expectMailbox(mailbox)) != ACCEPT) {
156 session.setLastError("Expected mailbox after COPY SPACE set SPACE");
157 return res;
158 }
159
160 if ((res = expectCRLF()) != ACCEPT) {
161 session.setLastError("Expected CRLF after COPY SPACE set SPACE mailbox");
162 return res;
163 }
164
165 c_in.setMailbox(mailbox);
166 c_in.setName("COPY");
167
168 return ACCEPT;
169}
virtual ParseResult parse(Request &) const
int getState(void) const
ProcessResult process(Depot &, Request &)
const std::string getName(void) const
virtual Mailbox * get(const std::string &path) const
Definition: depot.cc:107
virtual std::string mailboxToFilename(const std::string &m) const =0
virtual Mailbox * getSelected(void) const
Definition: depot.cc:183
unsigned int getSqnr() const
Definition: mailbox.cc:85
virtual bool rollBackNewMessages(void)=0
const std::string & getLastError(void) const
Definition: mailbox.cc:103
virtual iterator begin(const SequenceSet &bset, unsigned int mod=INCLUDE_EXPUNGED|SQNR_MODE) const =0
virtual bool commitNewMessages(const std::string &mbox)=0
virtual iterator end(void) const =0
@ SKIP_EXPUNGED
Definition: mailbox.h:69
virtual bool fastCopy(Message &source, Mailbox &desttype, const std::string &destname)=0
virtual Message * createMessage(const std::string &mbox, time_t idate=0)=0
const std::string getName(void) const
Definition: mailbox.cc:97
The Message class provides an interface for IMAP messages.
Definition: message.h:31
virtual void setInternalDate(time_t)=0
virtual time_t getInternalDate(void) const =0
virtual void close(void)=0
virtual unsigned int getUID(void) const =0
virtual void setStdFlag(unsigned char)=0
virtual bool appendChunk(const std::string &)=0
virtual unsigned char getStdFlags(void) const =0
virtual int readChunk(std::string &)=0
const std::string & getLastError(void) const
Definition: message.h:145
void setMailbox(const std::string &s_in)
Definition: imapparser.cc:155
SequenceSet bset
Definition: imapparser.h:115
void setName(const std::string &s_in)
Definition: imapparser.cc:70
const std::string & getMailbox(void) const
Definition: imapparser.cc:161
bool getUidMode(void) const
Definition: imapparser.cc:40
SequenceSet & getSet(void)
Definition: imapparser.cc:203
void setLastError(const std::string &error) const
Definition: session.cc:185
void setResponseCode(const std::string &error) const
Definition: session.cc:197
static Session & getInstance(void)
Definition: session.cc:33
Declaration of miscellaneous convertion functions.
Declaration of the IODevice class.
Declaration of the IOFactory class.
#define bincWarning
Definition: iofactory.h:44
Declaration of the Maildir class.
Definition: bincimapd.cc:9
std::string toImapString(const std::string &s_in)
Definition: convert.h:103
Operator::ParseResult expectSPACE(void)
std::string toCanonMailbox(const std::string &s_in)
Definition: convert.h:216
Operator::ParseResult expectSet(SequenceSet &s_in)
Operator::ParseResult expectCRLF(void)
Operator::ParseResult expectMailbox(std::string &s_in)
Declaration of all operators.
Declaration of a recursive descent IMAP command parser.