35static int numDeliveries = 0;
44 MessageMap::iterator it,
47 :
BaseIterator(1), mailbox(home), bset(_bset), mod(_mod), i(it)
56 bset(copy.bset), mod(copy.mod), i(copy.i), uidmax(copy.uidmax),
65 mailbox = copy.mailbox;
70 sqnrmax = copy.sqnrmax;
103 return b ? (i == b->i) :
false;
109 return !((*this) == a);
116 if (i == mailbox->messages.end())
119 Message &message = curMessage();
127 if (bset.isInSet(sqnr) || (!bset.isLimited() && sqnr == sqnrmax))
130 if (bset.isInSet(message.
getUID()) || (!bset.isLimited() && message.
getUID() == uidmax))
147 unsigned int mod)
const
149 beginIterator =
iterator((
Maildir *)
this, messages.begin(), bset, mod);
159 endIterator.bset, endIterator.mod);
166 MessageMap::iterator iter = i;
170 mailbox->index.remove(i->second.getUnique());
171 mailbox->messages.erase(i);
207 unsigned int exists = 0;
208 unsigned int recent = 0;
209 bool displayExists =
false;
222 mailboxchanged =
true;
223 displayExists =
true;
231 for (; i !=
end(); ++i) {
238 if (displayExists || exists != oldexists)
241 if (recent != oldrecent)
246 for (; i !=
end(); ++i) {
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)));
284 unlink((s_in +
"/bincimap-uidvalidity").c_str());
285 unlink((s_in +
"/bincimap-cache").c_str());
291 DIR *dirp = opendir((s_in +
"/new").c_str());
292 if (dirp == 0)
return false;
294 struct dirent *direntp;
295 while ((direntp = readdir(dirp)) != 0) {
296 string s = direntp->d_name;
298 && s.find(
'/') == string::npos
299 && s.find(
':') == string::npos) {
312 unsigned int statusid = 0;
314 if (stat((path +
"/new/").c_str(), &mystat) == 0)
315 statusid = mystat.st_ctime;
317 if (stat((path +
"/cur/").c_str(), &mystat) == 0)
318 statusid += mystat.st_ctime;
320 if (stat((path +
"/bincimap-cache").c_str(), &mystat) == 0)
321 statusid += mystat.st_ctime;
329 unsigned int messages = 0;
330 unsigned int unseen = 0;
331 unsigned int recent = 0;
333 unsigned int readUidValidity;
334 unsigned int readUidNext = 1;
335 map<string, bool> mincache;
337 const string cachefilename = path +
"/bincimap-cache";
338 FILE *fp = fopen(cachefilename.c_str(),
"r");
349 char cacheFileVersionBuffer[512];
351 if (sscanf(
inputBuffer,
"%s %u %u", cacheFileVersionBuffer,
352 &readUidValidity, &readUidNext) != 3
353 || strcmp(cacheFileVersionBuffer,
BINC_CACHE) != 0) {
361 unsigned int readUID;
362 unsigned int readSize;
363 unsigned int readInternalDate;
364 char readUnique[512];
368 &readInternalDate, &readSize, readUnique) != 4) {
376 mincache[readUnique] =
true;
381 s.
setUidValidity(readUidValidity < 1 ? time(0) : readUidValidity);
387 DIR *dirp = opendir((path +
"/new").c_str());
388 if (dirp == 0)
return false;
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)
407 if ((dirp = opendir((path +
"/cur").c_str())) == 0)
410 while ((direntp = readdir(dirp)) != 0) {
411 const string dname = direntp->d_name;
419 const string::size_type pos = dname.find(
':');
420 if (pos != string::npos) {
421 if (mincache.find(dname.substr(0, pos)) == mincache.end()) {
426 if (dname.substr(pos).find(
'S') == string::npos)
429 if (mincache.find(dname) == mincache.end()) {
451 MessageMap::const_iterator i = messages.end();
452 if (i == messages.begin())
459 if (i == messages.begin())
473 int sqnr = messages.size();
474 MessageMap::const_iterator i = messages.end();
475 if (i == messages.begin())
482 if (i == messages.begin())
509 string sname = mbox +
"/tmp/bincimap-XXXXXX";
510 char *safename = strdup(sname.c_str());
512 int fd = mkstemp(safename);
518 string safenameStr = safename;
527 newMessages.push_back(message);
528 vector<MaildirMessage>::iterator i = newMessages.end();
538 vector<MaildirMessage>::iterator i = newMessages.begin();
539 map<MaildirMessage *, string> committedMessages;
541 struct timeval youngestFile = {0, 0};
544 while (!abort && i != newMessages.end()) {
556 for (
int attempt = 0; !abort && attempt < 1000; ++attempt) {
558 gettimeofday(&tv, 0);
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");
571 ss << mbox <<
"/new/" << ssid.
str();
573 string fileName = ss.
str();
575 if (link(safeName.c_str(), fileName.c_str()) == 0) {
576 unlink(safeName.c_str());
580 committedMessages[&m] = fileName;
589 << strerror(errno) << endl;
605 for (i = newMessages.begin(); i != newMessages.end(); ++i)
606 unlink((*i).getSafeName().c_str());
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) {
615 bincWarning <<
"error rollbacking after failed commit to "
618 <<
": " << strerror(errno) << endl;
620 bincWarning <<
"error rollbacking after failed commit to "
623 <<
": " << strerror(errno) << endl;
641 gettimeofday(&tv, 0);
642 while (tv.tv_sec == youngestFile.tv_sec
643 && tv.tv_usec == youngestFile.tv_usec) {
644 gettimeofday(&tv, 0);
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);
652 int flags = j->first->getStdFlags();
660 string dest = mbox +
"/cur/" + basename +
":2," + flagStr;
661 if (rename(j->second.c_str(), dest.c_str()) == 0)
665 bincWarning <<
"when setting flags on: " << j->second
666 <<
": " << strerror(errno) << endl;
669 committedMessages.clear();
676 vector<MaildirMessage>::const_iterator i = newMessages.begin();
679 for (; i != newMessages.end(); ++i)
680 unlink((*i).getSafeName().c_str());
688 const std::string &destname)
710 for (
int attempt = 0; attempt < 1000; ++attempt) {
713 gettimeofday(&tv, 0);
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");
725 ss << destname <<
"/tmp/" << ssid.
str();
727 string fileName = ss.
str();
729 if (link((path +
"/cur/" + mfilename).c_str(), fileName.c_str()) == 0) {
735 newMessages.push_back(newmess);
745 << strerror(errno) << endl;
762 unsigned int uid = item->
uid;
763 if (messages.find(uid) == messages.end())
766 return &messages.find(uid)->second;
772 MessageMap::iterator it = messages.find(m.
getUID());
773 if (it != messages.end())
775 messages.insert(make_pair(m.
getUID(), m));
787 const string &fileName)
789 if (idx.find(unique) == idx.end()) {
796 if (uid != 0) item.
uid = uid;
797 if (fileName !=
"") item.
fileName = fileName;
804 map<string, MaildirIndexItem>::iterator it = idx.find(unique);
812 map<string, MaildirIndexItem>::iterator it = idx.find(unique);
828 map<string, MaildirIndexItem>::iterator it = idx.begin();
829 for (; it != idx.end(); ++it)
836 map<string, MaildirIndexItem>::iterator it = idx.begin();
837 for (; it != idx.end(); ++it)
838 it->second.fileName =
"";
const std::string & str(void) const
unsigned int getSqnr() const
void setLastError(const std::string &error) const
MaildirMessage & curMessage(void)
Message & operator*(void)
iterator & operator=(const iterator ©)
bool operator!=(const BaseIterator &) const
bool operator==(const BaseIterator &) const
void bumpUidValidity(const std::string &) const
const std::string getTypeName(void) const
unsigned int getUidValidity(void) const
void add(MaildirMessage &m)
unsigned int getStatusID(const std::string &) const
bool fastCopy(Message &source, Mailbox &desttype, const std::string &destname)
Mailbox::iterator end(void) const
bool commitNewMessages(const std::string &mbox)
ScanResult scan(bool forceScan=false)
unsigned int getMaxSqnr(void) const
bool isMailbox(const std::string &) const
void setPath(const std::string &path_in)
Message * createMessage(const std::string &mbox, time_t idate=0)
bool getUpdates(bool doscan, unsigned int type, PendingUpdates &updates, bool forceScan)
unsigned int getMaxUid(void) const
Mailbox::iterator begin(const SequenceSet &bset, unsigned int mod=INCLUDE_EXPUNGED|SQNR_MODE) const
bool isMarked(const std::string &) const
MaildirMessage * get(const std::string &id)
bool getStatus(const std::string &, Status &) const
bool rollBackNewMessages(void)
unsigned int getUidNext(void) const
void clearFileNames(void)
void insert(const std::string &unique, unsigned int uid, const std::string &fileName="")
unsigned int getSize(void) const
MaildirIndexItem * find(const std::string &unique)
void remove(const std::string &unique)
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.
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)
void setLastError(const std::string &error) const
void setResponseCode(const std::string &error) const
static Session & getInstance(void)
std::string getEnv(const std::string &key)
void setUidValidity(int i)
Declaration of miscellaneous convertion functions.
Declaration of the IODevice class.
Declaration of the IOFactory class.
Declaration of the Maildir class.
Declaration of the MaildirMessage class.
std::string toImapString(const std::string &s_in)
std::stack< int > inputBuffer
Declaration of the Status class.