Bincimap 2.0.16
Easy Imapping
Loading...
Searching...
No Matches
maildir.cc
Go to the documentation of this file.
1
7#include <iostream>
8#include <iomanip>
9#include <algorithm>
10
11#include <ctype.h>
12#include <dirent.h>
13#include <errno.h>
14#include <fcntl.h>
15#include <stdio.h>
16#include <sys/stat.h>
17#include <sys/time.h>
18#include <sys/types.h>
19#include <unistd.h>
20
21#include "convert.h"
22#include "iodevice.h"
23#include "iofactory.h"
24#include "maildir.h"
25#include "maildirmessage.h"
26#include "pendingupdates.h"
27#include "session.h"
28#include "status.h"
29#include "globals.h"
30
31using namespace ::std;
32using namespace Binc;
33
34// Used to generate the unique names for Maildir delivery
35static int numDeliveries = 0;
36
37//------------------------------------------------------------------------
39{
40}
41
42//------------------------------------------------------------------------
44 MessageMap::iterator it,
45 const SequenceSet &_bset,
46 unsigned int _mod)
47 : BaseIterator(1), mailbox(home), bset(_bset), mod(_mod), i(it)
48{
49 uidmax = home->getMaxUid();
50 sqnrmax = home->getMaxSqnr();
51}
52
53//------------------------------------------------------------------------
55 : BaseIterator(copy.sqnr), mailbox(copy.mailbox),
56 bset(copy.bset), mod(copy.mod), i(copy.i), uidmax(copy.uidmax),
57 sqnrmax(copy.sqnrmax)
58{
59}
60
61//------------------------------------------------------------------------
63{
64 sqnr = copy.sqnr;
65 mailbox = copy.mailbox;
66 bset = copy.bset;
67 mod = copy.mod;
68 i = copy.i;
69 uidmax = copy.uidmax;
70 sqnrmax = copy.sqnrmax;
71 return *this;
72}
73
74//------------------------------------------------------------------------
76{
77}
78
79//------------------------------------------------------------------------
81{
82 return i->second;
83}
84
85//------------------------------------------------------------------------
87{
88 return curMessage();
89}
90
91//------------------------------------------------------------------------
93{
94 ++i;
95 ++sqnr;
96 reposition();
97}
98
99//------------------------------------------------------------------------
101{
102 const iterator *b = dynamic_cast<const iterator *>(&a);
103 return b ? (i == b->i) : false;
104}
105
106//------------------------------------------------------------------------
108{
109 return !((*this) == a);
110}
111
112//------------------------------------------------------------------------
114{
115 for (;;) {
116 if (i == mailbox->messages.end())
117 break;
118
119 Message &message = curMessage();
120 if ((mod & SKIP_EXPUNGED) && message.isExpunged()) {
121 ++i;
122 continue;
123 }
124
125 bool inset = false;
126 if (mod & SQNR_MODE) {
127 if (bset.isInSet(sqnr) || (!bset.isLimited() && sqnr == sqnrmax))
128 inset = true;
129 } else {
130 if (bset.isInSet(message.getUID()) || (!bset.isLimited() && message.getUID() == uidmax))
131 inset = true;
132 }
133
134 if (!inset) {
135 ++i;
136 if (!message.isExpunged())
137 ++sqnr;
138 continue;
139 }
140
141 break;
142 }
143}
144
145//------------------------------------------------------------------------
147 unsigned int mod) const
148{
149 beginIterator = iterator((Maildir *)this, messages.begin(), bset, mod);
150 beginIterator.reposition();
151
152 return Mailbox::iterator(beginIterator);
153}
154
155//------------------------------------------------------------------------
157{
158 endIterator = iterator((Maildir *)this, messages.end(),
159 endIterator.bset, endIterator.mod);
160 return Mailbox::iterator(endIterator);
161}
162
163//------------------------------------------------------------------------
165{
166 MessageMap::iterator iter = i;
167 ++iter;
168
170 mailbox->index.remove(i->second.getUnique());
171 mailbox->messages.erase(i);
172
173 i = iter;
174 reposition();
175}
176
177//------------------------------------------------------------------------
179{
180 firstscan = true;
181 cacheRead = false;
182 uidvalidity = 0;
183 uidnext = 1;
184 selected = false;
185 oldrecent = 0;
186 oldexists = 0;
187}
188
189//------------------------------------------------------------------------
191{
192}
193
194//------------------------------------------------------------------------
195void Maildir::setPath(const string &path_in)
196{
197 path = path_in;
198}
199
200//------------------------------------------------------------------------
201bool Maildir::getUpdates(bool doscan, unsigned int type,
202 PendingUpdates &updates, bool forceScan)
203{
204 if (doscan && scan(forceScan) != Success)
205 return false;
206
207 unsigned int exists = 0;
208 unsigned int recent = 0;
209 bool displayExists = false;
210
211 // count messages, find recent
212 if (!readOnly && (type & PendingUpdates::EXPUNGE)) {
215
216 while (i != end()) {
217 Message &message = *i;
218
219 if (message.isExpunged()) {
220 updates.addExpunged(i.getSqnr());
221 i.erase();
222 mailboxchanged = true;
223 displayExists = true;
224 } else
225 ++i;
226 }
227 }
228
231 for (; i != end(); ++i) {
232 Message & message = *i;
233 // at this point, there is a message that is not expunged
234 ++exists;
235 if (message.getStdFlags() & Message::F_RECENT) ++recent;
236 }
237
238 if (displayExists || exists != oldexists)
239 updates.setExists(oldexists = exists);
240
241 if (recent != oldrecent)
242 updates.setRecent(oldrecent = recent);
243
244 if (type & PendingUpdates::FLAGS) {
246 for (; i != end(); ++i) {
247 Message &message = *i;
248 if (message.hasFlagsChanged()) {
249 int flags = message.getStdFlags();
250
251 updates.addFlagUpdates(i.getSqnr(), message.getUID(), flags,
252 message.getCustomFlags());
253
254 message.setFlagsUnchanged();
255 }
256 }
257 }
258
259 return true;
260}
261
262//------------------------------------------------------------------------
263bool Maildir::isMailbox(const std::string &s_in) const
264{
265 struct stat mystat;
266
267 return ((stat((s_in + "/cur").c_str(), &mystat) == 0
268 && S_ISDIR(mystat.st_mode))
269 && (stat((s_in + "/new").c_str(), &mystat) == 0
270 && S_ISDIR(mystat.st_mode))
271 && (stat((s_in + "/tmp").c_str(), &mystat) == 0
272 && S_ISDIR(mystat.st_mode)));
273}
274
275//------------------------------------------------------------------------
276const std::string Maildir::getTypeName(void) const
277{
278 return "Maildir";
279}
280
281//------------------------------------------------------------------------
282void Maildir::bumpUidValidity(const string &s_in) const
283{
284 unlink((s_in + "/bincimap-uidvalidity").c_str());
285 unlink((s_in + "/bincimap-cache").c_str());
286}
287
288//------------------------------------------------------------------------
289bool Maildir::isMarked(const std::string &s_in) const
290{
291 DIR *dirp = opendir((s_in + "/new").c_str());
292 if (dirp == 0) return false;
293
294 struct dirent *direntp;
295 while ((direntp = readdir(dirp)) != 0) {
296 string s = direntp->d_name;
297 if (s[0] != '.'
298 && s.find('/') == string::npos
299 && s.find(':') == string::npos) {
300 closedir(dirp);
301 return true;
302 }
303 }
304
305 closedir(dirp);
306 return false;
307}
308
309//------------------------------------------------------------------------
310unsigned int Maildir::getStatusID(const string &path) const
311{
312 unsigned int statusid = 0;
313 struct stat mystat;
314 if (stat((path + "/new/").c_str(), &mystat) == 0)
315 statusid = mystat.st_ctime;
316
317 if (stat((path + "/cur/").c_str(), &mystat) == 0)
318 statusid += mystat.st_ctime;
319
320 if (stat((path + "/bincimap-cache").c_str(), &mystat) == 0)
321 statusid += mystat.st_ctime;
322
323 return statusid;
324}
325
326//------------------------------------------------------------------------
327bool Maildir::getStatus(const string &path, Status &s) const
328{
329 unsigned int messages = 0;
330 unsigned int unseen = 0;
331 unsigned int recent = 0;
332
333 unsigned int readUidValidity;
334 unsigned int readUidNext = 1;
335 map<string, bool> mincache;
336
337 const string cachefilename = path + "/bincimap-cache";
338 FILE *fp = fopen(cachefilename.c_str(), "r");
339 if (fp) do {
340 char inputBuffer[512];
341 if (!fgets(inputBuffer, sizeof(inputBuffer), fp)) {
342 fclose(fp);
343 return false;
344 }
345
346 // terminate the buffer
347 inputBuffer[sizeof(inputBuffer) - 1] = '\0';
348
349 char cacheFileVersionBuffer[512];
350
351 if (sscanf(inputBuffer, "%s %u %u", cacheFileVersionBuffer,
352 &readUidValidity, &readUidNext) != 3
353 || strcmp(cacheFileVersionBuffer, BINC_CACHE) != 0) {
354 fclose(fp);
355 readUidValidity = 0;
356 readUidNext = 1;
357 mincache.clear();
358 break;
359 }
360
361 unsigned int readUID;
362 unsigned int readSize;
363 unsigned int readInternalDate;
364 char readUnique[512];
365 while (fgets(inputBuffer, sizeof(inputBuffer), fp)) {
366 inputBuffer[sizeof(inputBuffer) - 1] = '\0';
367 if (sscanf(inputBuffer, "%u %u %u %s", &readUID,
368 &readInternalDate, &readSize, readUnique) != 4) {
369 fclose(fp);
370 readUidValidity = 0;
371 readUidNext = 1;
372 mincache.clear();
373 break;
374 }
375
376 mincache[readUnique] = true;
377 }
378
379 fclose(fp);
380
381 s.setUidValidity(readUidValidity < 1 ? time(0) : readUidValidity);
382 } while (0); else {
383 s.setUidValidity(time(0));
384 }
385
386 // Scan new
387 DIR *dirp = opendir((path + "/new").c_str());
388 if (dirp == 0) return false;
389
390 struct dirent *direntp;
391 while ((direntp = readdir(dirp)) != 0) {
392 const string filename = direntp->d_name;
393 if (filename[0] == '.'
394 || filename.find(':') != string::npos
395 || filename.find('/') != string::npos)
396 continue;
397
398 ++recent;
399 ++readUidNext;
400 ++unseen;
401 ++messages;
402 }
403
404 closedir(dirp);
405
406 // Scan cur
407 if ((dirp = opendir((path + "/cur").c_str())) == 0)
408 return false;
409
410 while ((direntp = readdir(dirp)) != 0) {
411 const string dname = direntp->d_name;
412 if (dname[0] == '.')
413 continue;
414
415 ++messages;
416
417 // Add to unseen if it doesn't have the seen flag or if it has no
418 // flags.
419 const string::size_type pos = dname.find(':');
420 if (pos != string::npos) {
421 if (mincache.find(dname.substr(0, pos)) == mincache.end()) {
422 ++recent;
423 ++readUidNext;
424 }
425
426 if (dname.substr(pos).find('S') == string::npos)
427 ++unseen;
428 } else {
429 if (mincache.find(dname) == mincache.end()) {
430 ++recent;
431 ++readUidNext;
432 }
433
434 ++unseen;
435 }
436 }
437
438 closedir(dirp);
439
440 s.setRecent(recent);
441 s.setMessages(messages);
442 s.setUnseen(unseen);
443 s.setUidNext(uidnext);
444
445 return true;
446}
447
448//------------------------------------------------------------------------
449unsigned int Maildir::getMaxUid(void) const
450{
451 MessageMap::const_iterator i = messages.end();
452 if (i == messages.begin())
453 return 0;
454
455 --i;
456 for (;;) {
457 const MaildirMessage &message = i->second;
458 if (message.isExpunged()) {
459 if (i == messages.begin())
460 return 0;
461 --i;
462 } else {
463 return message.getUID();
464 }
465 }
466
467 return 0;
468}
469
470//------------------------------------------------------------------------
471unsigned int Maildir::getMaxSqnr(void) const
472{
473 int sqnr = messages.size();
474 MessageMap::const_iterator i = messages.end();
475 if (i == messages.begin())
476 return 0;
477
478 --i;
479 for (;;) {
480 const MaildirMessage &message = i->second;
481 if (message.isExpunged()) {
482 if (i == messages.begin())
483 return 0;
484 --sqnr;
485 --i;
486 } else {
487 return sqnr;
488 }
489 }
490
491 return 0;
492}
493
494//------------------------------------------------------------------------
495unsigned int Maildir::getUidValidity(void) const
496{
497 return uidvalidity;
498}
499
500//------------------------------------------------------------------------
501unsigned int Maildir::getUidNext(void) const
502{
503 return uidnext;
504}
505
506//------------------------------------------------------------------------
507Message *Maildir::createMessage(const string &mbox, time_t idate)
508{
509 string sname = mbox + "/tmp/bincimap-XXXXXX";
510 char *safename = strdup(sname.c_str());
511
512 int fd = mkstemp(safename);
513 if (fd == -1) {
514 setLastError("Unable to create safe name.");
515 return 0;
516 }
517
518 string safenameStr = safename;
519 delete[] safename;
520
521 MaildirMessage message(*this);
522
523 message.setFile(fd);
524 message.setSafeName(safenameStr);
525 message.setInternalDate(idate);
526
527 newMessages.push_back(message);
528 vector<MaildirMessage>::iterator i = newMessages.end();
529 --i;
530 return &(*i);
531}
532
533//------------------------------------------------------------------------
534bool Maildir::commitNewMessages(const string &mbox)
535{
536 Session &session = Session::getInstance();
537
538 vector<MaildirMessage>::iterator i = newMessages.begin();
539 map<MaildirMessage *, string> committedMessages;
540
541 struct timeval youngestFile = {0, 0};
542
543 bool abort = false;
544 while (!abort && i != newMessages.end()) {
545 MaildirMessage &m = *i;
546
548 ++i;
549 continue;
550 }
551
553
554 string safeName = m.getSafeName();
555
556 for (int attempt = 0; !abort && attempt < 1000; ++attempt) {
557 struct timeval tv;
558 gettimeofday(&tv, 0);
559 youngestFile = tv;
560
561 // Generate Maildir conformant file name
562 BincStream ssid;
563 ssid << (int) tv.tv_sec << "."
564 << "R" << (int) rand()
565 << "M" << (int) tv.tv_usec
566 << "P" << (int) session.getPid()
567 << "Q" << numDeliveries++
568 << "." << session.getEnv("TCPLOCALHOST");
569
570 BincStream ss;
571 ss << mbox << "/new/" << ssid.str();
572
573 string fileName = ss.str();
574
575 if (link(safeName.c_str(), fileName.c_str()) == 0) {
576 unlink(safeName.c_str());
577 m.setInternalDate(tv.tv_sec);
578 m.setUnique(ssid.str());
579 m.setUID(0);
580 committedMessages[&m] = fileName;
581 break;
582 }
583
584 if (errno == EEXIST)
585 continue;
586
587 bincWarning << "link(" << toImapString(safeName) << ", "
588 << toImapString(fileName) << ") failed: "
589 << strerror(errno) << endl;
590
591 session.setResponseCode("TRYCREATE");
592 session.setLastError("failed, internal error.");
593 abort = true;
594 break;
595 }
596
597 ++i;
598 }
599
600 // abort means to make an attempt to restore the mailbox to
601 // its original state.
602 if (abort) {
603 // Fixme: Messages that are in committedMessages should be skipped
604 // here.
605 for (i = newMessages.begin(); i != newMessages.end(); ++i)
606 unlink((*i).getSafeName().c_str());
607
608 map<MaildirMessage *, string>::const_iterator j
609 = committedMessages.begin();
610 while (j != committedMessages.end()) {
611 if (unlink(j->second.c_str()) != 0) {
612 if (errno == ENOENT) {
613 // FIXME: The message was probably moves away from new/ by
614 // another IMAP session.
615 bincWarning << "error rollbacking after failed commit to "
616 << toImapString(mbox) << ", failed to unlink "
617 << toImapString(j->second)
618 << ": " << strerror(errno) << endl;
619 } else {
620 bincWarning << "error rollbacking after failed commit to "
621 << toImapString(mbox) << ", failed to unlink "
622 << toImapString(j->second)
623 << ": " << strerror(errno) << endl;
624 newMessages.clear();
625 return false;
626 }
627 }
628
629 ++j;
630 }
631
632 newMessages.clear();
633 return false;
634 }
635
636 // cover the extremely unlikely event that another concurrent
637 // Maildir accessor has just made a file with the same timestamp and
638 // random number by spinning until the timestamp has changed before
639 // moving the message into cur.
640 struct timeval tv;
641 gettimeofday(&tv, 0);
642 while (tv.tv_sec == youngestFile.tv_sec
643 && tv.tv_usec == youngestFile.tv_usec) {
644 gettimeofday(&tv, 0);
645 }
646
647 map<MaildirMessage *, string>::const_iterator j
648 = committedMessages.begin();
649 for (;j != committedMessages.end(); ++j) {
650 string basename = j->second.substr(j->second.rfind('/') + 1);
651
652 int flags = j->first->getStdFlags();
653 string flagStr;
654 if (flags & Message::F_DRAFT) flagStr += "D";
655 if (flags & Message::F_FLAGGED) flagStr += "F";
656 if (flags & Message::F_ANSWERED) flagStr += "R";
657 if (flags & Message::F_SEEN) flagStr += "S";
658 if (flags & Message::F_DELETED) flagStr += "T";
659
660 string dest = mbox + "/cur/" + basename + ":2," + flagStr;
661 if (rename(j->second.c_str(), dest.c_str()) == 0)
662 continue;
663
664 if (errno != ENOENT)
665 bincWarning << "when setting flags on: " << j->second
666 << ": " << strerror(errno) << endl;
667 }
668
669 committedMessages.clear();
670 return true;
671}
672
673//------------------------------------------------------------------------
675{
676 vector<MaildirMessage>::const_iterator i = newMessages.begin();
677 // Fixme: Messages that are in committedMessages should be skipped
678 // here.
679 for (; i != newMessages.end(); ++i)
680 unlink((*i).getSafeName().c_str());
681
682 newMessages.clear();
683 return true;
684}
685
686//------------------------------------------------------------------------
688 const std::string &destname)
689{
690 // At this point, fastCopy is broken because the creation time is
691 // equal for the two clones. The new clone must have a new creation
692 // time. Symlinks are a possibility, but they break if other Maildir
693 // accessors rename mailboxes.
694 // return false;
695
696 Session &session = Session::getInstance();
697
698 MaildirMessage *message = dynamic_cast<MaildirMessage *>(&m);
699 if (!message)
700 return false;
701
702 string mfilename = message->getFileName();
703 if (mfilename == "")
704 return false;
705
706 Maildir *mailbox = dynamic_cast<Maildir *>(&desttype);
707 if (!mailbox)
708 return false;
709
710 for (int attempt = 0; attempt < 1000; ++attempt) {
711
712 struct timeval tv;
713 gettimeofday(&tv, 0);
714
715 // Generate Maildir conformant file name
716 BincStream ssid;
717 ssid << (int) tv.tv_sec << "."
718 << "R" << (int) rand()
719 << "M" << (int) tv.tv_usec
720 << "P" << (int) session.getPid()
721 << "Q" << numDeliveries++
722 << "." << session.getEnv("TCPLOCALHOST");
723
724 BincStream ss;
725 ss << destname << "/tmp/" << ssid.str();
726
727 string fileName = ss.str();
728
729 if (link((path + "/cur/" + mfilename).c_str(), fileName.c_str()) == 0) {
730 MaildirMessage newmess = *message;
731 newmess.setSafeName(fileName);
732 newmess.setUnique(ssid.str());
733 newmess.setInternalDate((time_t) tv.tv_sec);
734 newmess.setUID(0);
735 newMessages.push_back(newmess);
736 break;
737 }
738
739 if (errno == EEXIST)
740 continue;
741
742 bincWarning << "Warning: link("
743 << toImapString(path + "/cur/" + mfilename)
744 << ", " << toImapString(fileName) << ") failed: "
745 << strerror(errno) << endl;
746
747 session.setResponseCode("TRYCREATE");
748 session.setLastError("failed, internal error.");
749 return false;
750 }
751
752 return true;
753}
754
755//------------------------------------------------------------------------
756MaildirMessage *Maildir::get(const std::string &id)
757{
758 MaildirIndexItem *item = index.find(id);
759 if (!item)
760 return 0;
761
762 unsigned int uid = item->uid;
763 if (messages.find(uid) == messages.end())
764 return 0;
765
766 return &messages.find(uid)->second;
767}
768
769//------------------------------------------------------------------------
771{
772 MessageMap::iterator it = messages.find(m.getUID());
773 if (it != messages.end())
774 messages.erase(it);
775 messages.insert(make_pair(m.getUID(), m));
776 index.insert(m.getUnique(), m.getUID());
777}
778
779//------------------------------------------------------------------------
780unsigned int MaildirIndex::getSize(void) const
781{
782 return idx.size();
783}
784
785//------------------------------------------------------------------------
786void MaildirIndex::insert(const string &unique, unsigned int uid,
787 const string &fileName)
788{
789 if (idx.find(unique) == idx.end()) {
790 MaildirIndexItem item;
791 item.uid = uid;
792 item.fileName = fileName;
793 idx[unique] = item;
794 } else {
795 MaildirIndexItem &item = idx[unique];
796 if (uid != 0) item.uid = uid;
797 if (fileName != "") item.fileName = fileName;
798 }
799}
800
801//------------------------------------------------------------------------
802void MaildirIndex::remove(const string &unique)
803{
804 map<string, MaildirIndexItem>::iterator it = idx.find(unique);
805 if (it != idx.end())
806 idx.erase(it);
807}
808
809//------------------------------------------------------------------------
811{
812 map<string, MaildirIndexItem>::iterator it = idx.find(unique);
813 if (it != idx.end())
814 return &it->second;
815
816 return 0;
817}
818
819//------------------------------------------------------------------------
821{
822 idx.clear();
823}
824
825//------------------------------------------------------------------------
827{
828 map<string, MaildirIndexItem>::iterator it = idx.begin();
829 for (; it != idx.end(); ++it)
830 it->second.uid = 0;
831}
832
833//------------------------------------------------------------------------
835{
836 map<string, MaildirIndexItem>::iterator it = idx.begin();
837 for (; it != idx.end(); ++it)
838 it->second.fileName = "";
839}
const std::string & str(void) const
Definition: convert.cc:58
unsigned int getSqnr() const
Definition: mailbox.cc:85
void setLastError(const std::string &error) const
Definition: mailbox.cc:109
bool readOnly
Definition: mailbox.h:125
@ SKIP_EXPUNGED
Definition: mailbox.h:69
@ INCLUDE_EXPUNGED
Definition: mailbox.h:68
void operator++(void)
Definition: maildir.cc:92
MaildirMessage & curMessage(void)
Definition: maildir.cc:80
Message & operator*(void)
Definition: maildir.cc:86
void reposition(void)
Definition: maildir.cc:113
iterator & operator=(const iterator &copy)
Definition: maildir.cc:62
bool operator!=(const BaseIterator &) const
Definition: maildir.cc:107
bool operator==(const BaseIterator &) const
Definition: maildir.cc:100
void bumpUidValidity(const std::string &) const
Definition: maildir.cc:282
const std::string getTypeName(void) const
Definition: maildir.cc:276
unsigned int getUidValidity(void) const
Definition: maildir.cc:495
~Maildir(void)
Definition: maildir.cc:190
void add(MaildirMessage &m)
Definition: maildir.cc:770
unsigned int getStatusID(const std::string &) const
Definition: maildir.cc:310
bool fastCopy(Message &source, Mailbox &desttype, const std::string &destname)
Definition: maildir.cc:687
Mailbox::iterator end(void) const
Definition: maildir.cc:156
bool commitNewMessages(const std::string &mbox)
Definition: maildir.cc:534
Maildir(void)
Definition: maildir.cc:178
ScanResult scan(bool forceScan=false)
Definition: maildir-scan.cc:70
unsigned int getMaxSqnr(void) const
Definition: maildir.cc:471
bool isMailbox(const std::string &) const
Definition: maildir.cc:263
void setPath(const std::string &path_in)
Definition: maildir.cc:195
Message * createMessage(const std::string &mbox, time_t idate=0)
Definition: maildir.cc:507
bool getUpdates(bool doscan, unsigned int type, PendingUpdates &updates, bool forceScan)
Definition: maildir.cc:201
unsigned int getMaxUid(void) const
Definition: maildir.cc:449
Mailbox::iterator begin(const SequenceSet &bset, unsigned int mod=INCLUDE_EXPUNGED|SQNR_MODE) const
Definition: maildir.cc:146
bool isMarked(const std::string &) const
Definition: maildir.cc:289
MaildirMessage * get(const std::string &id)
Definition: maildir.cc:756
bool getStatus(const std::string &, Status &) const
Definition: maildir.cc:327
bool rollBackNewMessages(void)
Definition: maildir.cc:674
unsigned int getUidNext(void) const
Definition: maildir.cc:501
void clearFileNames(void)
Definition: maildir.cc:834
void insert(const std::string &unique, unsigned int uid, const std::string &fileName="")
Definition: maildir.cc:786
void clearUids(void)
Definition: maildir.cc:826
unsigned int getSize(void) const
Definition: maildir.cc:780
MaildirIndexItem * find(const std::string &unique)
Definition: maildir.cc:810
void remove(const std::string &unique)
Definition: maildir.cc:802
void clear(void)
Definition: maildir.cc:820
unsigned int uid
Definition: maildir.h:33
std::string fileName
Definition: maildir.h:34
static MaildirMessageCache & getInstance(void)
void removeStatus(const MaildirMessage *)
The MaildirMessage class provides an interface for IMAP messages.
void setUnique(const std::string &s_in)
void setInternalDate(time_t internaldate)
unsigned char getInternalFlags(void) const
void setUID(unsigned int uid)
unsigned int getUID(void) const
const std::string & getSafeName(void) const
void setSafeName(const std::string &name)
void setInternalFlag(unsigned char flags)
std::string getFileName(void) const
const std::string & getUnique(void) const
bool isExpunged(void) const
The Message class provides an interface for IMAP messages.
Definition: message.h:31
virtual unsigned int getUID(void) const =0
virtual void setFlagsUnchanged(void)=0
virtual bool isExpunged(void) const =0
virtual unsigned char getStdFlags(void) const =0
virtual std::vector< std::string > getCustomFlags(void) const =0
virtual bool hasFlagsChanged(void) const =0
void addFlagUpdates(unsigned int sqnr, unsigned int uid, unsigned int flags, const std::vector< std::string > &cflags)
void setExists(unsigned int n)
void addExpunged(unsigned int uid)
void setRecent(unsigned int n)
static SequenceSet & all(void)
Definition: imapparser.cc:261
void setLastError(const std::string &error) const
Definition: session.cc:185
void setResponseCode(const std::string &error) const
Definition: session.cc:197
pid_t getPid(void)
Definition: session.cc:209
static Session & getInstance(void)
Definition: session.cc:33
std::string getEnv(const std::string &key)
Definition: session.cc:230
void setMessages(int i)
Definition: status.h:28
void setUidValidity(int i)
Definition: status.h:32
void setUidNext(int i)
Definition: status.h:33
void setRecent(int i)
Definition: status.h:29
void setUnseen(int i)
Definition: status.h:31
Declaration of miscellaneous convertion functions.
Global constants.
#define BINC_CACHE
Definition: globals.h:12
Declaration of the IODevice class.
Declaration of the IOFactory class.
#define bincWarning
Definition: iofactory.h:44
Declaration of the Maildir class.
Declaration of the MaildirMessage class.
Definition: bincimapd.cc:9
std::string toImapString(const std::string &s_in)
Definition: convert.h:103
std::stack< int > inputBuffer
Declaration of the Status class.