summaryrefslogtreecommitdiff
path: root/src/maildir-scan.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/maildir-scan.cc')
-rw-r--r--src/maildir-scan.cc191
1 files changed, 95 insertions, 96 deletions
diff --git a/src/maildir-scan.cc b/src/maildir-scan.cc
index 4628d5b..2f3a9b4 100644
--- a/src/maildir-scan.cc
+++ b/src/maildir-scan.cc
@@ -4,16 +4,17 @@
* @author Andreas Aardal Hanssen
* @date 2002-2005
* ----------------------------------------------------------------- **/
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
#include "iodevice.h"
#include "iofactory.h"
#include "maildir.h"
+#include <errno.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
using namespace Binc;
using namespace ::std;
@@ -22,11 +23,9 @@ Lock::Lock(const string &path)
lock = (path == "" ? "." : path) + "/bincimap-scan-lock";
int lockfd = -1;
- while ((lockfd = ::open(lock.c_str(),
- O_CREAT | O_WRONLY | O_EXCL, 0666)) == -1) {
+ while ((lockfd = ::open(lock.c_str(), O_CREAT | O_WRONLY | O_EXCL, 0666)) == -1) {
if (errno != EEXIST) {
- bincWarning << "unable to lock mailbox: " << lock
- << ", " << string(strerror(errno)) << endl;
+ bincWarning << "unable to lock mailbox: " << lock << ", " << string(strerror(errno)) << endl;
return;
}
@@ -34,14 +33,15 @@ Lock::Lock(const string &path)
bincWarning << "waiting for mailbox lock " << lock << "." << endl;
if (lstat(lock.c_str(), &mystat) == 0) {
if ((time(0) - mystat.st_ctime) > 300) {
- if (unlink(lock.c_str()) == 0) continue;
- else bincWarning << "failed to force mailbox lock: " << lock
- << ", " << string(strerror(errno)) << endl;
+ if (unlink(lock.c_str()) == 0)
+ continue;
+ else
+ bincWarning << "failed to force mailbox lock: " << lock << ", " << string(strerror(errno))
+ << endl;
}
} else {
if (errno != ENOENT) {
- string err = "invalid lock " + lock + ": "
- + strerror(errno);
+ string err = "invalid lock " + lock + ": " + strerror(errno);
bincWarning << err << endl;
return;
}
@@ -58,8 +58,7 @@ Lock::~Lock()
{
// remove the lock
if (unlink(lock.c_str()) != 0)
- bincWarning << "failed to unlock mailbox: " << lock << ", "
- << strerror(errno) << endl;
+ bincWarning << "failed to unlock mailbox: " << lock << ", " << strerror(errno) << endl;
}
//------------------------------------------------------------------------
@@ -77,8 +76,7 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
if (firstscan || forceScan) {
struct stat oldstat;
if (stat(newpath.c_str(), &oldstat) != 0) {
- setLastError("Invalid Mailbox, " + newpath + ": "
- + string(strerror(errno)));
+ setLastError("Invalid Mailbox, " + newpath + ": " + string(strerror(errno)));
return PermanentError;
}
@@ -86,8 +84,7 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
old_new_st_ctime = oldstat.st_ctime;
if (stat(curpath.c_str(), &oldstat) != 0) {
- setLastError("Invalid Mailbox, " + curpath + ": "
- + string(strerror(errno)));
+ setLastError("Invalid Mailbox, " + curpath + ": " + string(strerror(errno)));
return PermanentError;
}
@@ -106,14 +103,12 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
struct stat oldnewstat;
struct stat oldbincimapcachestat;
if (stat(newpath.c_str(), &oldnewstat) != 0) {
- setLastError("Invalid Mailbox, " + newpath + ": "
- + string(strerror(errno)));
+ setLastError("Invalid Mailbox, " + newpath + ": " + string(strerror(errno)));
return PermanentError;
}
if (stat(curpath.c_str(), &oldcurstat) != 0) {
- setLastError("Invalid Mailbox, " + curpath + ": "
- + string(strerror(errno)));
+ setLastError("Invalid Mailbox, " + curpath + ": " + string(strerror(errno)));
return PermanentError;
}
@@ -122,12 +117,11 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
oldbincimapcachestat.st_mtime = 0;
}
- if (oldnewstat.st_mtime == old_new_st_mtime
- && oldnewstat.st_ctime == old_new_st_ctime
- && oldcurstat.st_mtime == old_cur_st_mtime
- && oldcurstat.st_ctime == old_cur_st_ctime
+ if (oldnewstat.st_mtime == old_new_st_mtime && oldnewstat.st_ctime == old_new_st_ctime
+ && oldcurstat.st_mtime == old_cur_st_mtime && oldcurstat.st_ctime == old_cur_st_ctime
&& oldbincimapcachestat.st_mtime == old_bincimap_cache_st_mtime
- && oldbincimapcachestat.st_ctime == old_bincimap_cache_st_ctime) {
+ && oldbincimapcachestat.st_ctime == old_bincimap_cache_st_ctime)
+ {
return Success;
}
@@ -148,21 +142,21 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
// changes to the depot across Binc IMAP instances that can not be
// communicated via the depot itself.
switch (readCache()) {
- case NoCache:
- case Error:
+ case NoCache:
+ case Error:
// An error with reading the cache files when it's not the first
// time we scan the depot is treated as an error.
- if (!firstscan && !readOnly) {
- old_cur_st_mtime = (time_t) 0;
- old_cur_st_ctime = (time_t) 0;
- old_new_st_mtime = (time_t) 0;
- old_new_st_ctime = (time_t) 0;
- return TemporaryError;
- }
- mailboxchanged = true;
- break;
- default:
- break;
+ if (!firstscan && !readOnly) {
+ old_cur_st_mtime = (time_t)0;
+ old_cur_st_ctime = (time_t)0;
+ old_new_st_mtime = (time_t)0;
+ old_new_st_ctime = (time_t)0;
+ return TemporaryError;
+ }
+ mailboxchanged = true;
+ break;
+ default:
+ break;
}
// open new/ directory
@@ -185,9 +179,7 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
// start with a dot. Do not try to extract information from unique
// names." - The Maildir spec from cr.yp.to
string filename = pdirent->d_name;
- if (filename[0] == '.'
- || filename.find(':') != string::npos
- || filename.find('/') != string::npos)
+ if (filename[0] == '.' || filename.find(':') != string::npos || filename.find('/') != string::npos)
continue;
string fullfilename = newpath + filename;
@@ -201,24 +193,23 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
if (stat(fullfilename.c_str(), &mystat) != 0) {
if (errno == ENOENT) {
// prevent looping due to stale symlinks
- if (lstat(fullfilename.c_str(), &mystat) == 0) {
- bincWarning << "dangling symlink: " << fullfilename << endl;
+ if (lstat(fullfilename.c_str(), &mystat) == 0) {
+ bincWarning << "dangling symlink: " << fullfilename << endl;
continue;
}
- // a rare race between readdir and stat force us to restart the scan.
+ // a rare race between readdir and stat force us to restart the scan.
closedir(pdir);
if ((pdir = opendir(newpath.c_str())) == 0) {
string reason = "Warning: opendir(\"" + newpath + "\") == 0 (";
- reason += strerror(errno);
- reason += ")";
+ reason += strerror(errno);
+ reason += ")";
setLastError(reason);
return PermanentError;
}
} else
- bincWarning << "junk in Maildir: \"" << fullfilename << "\": "
- << strerror(errno);
+ bincWarning << "junk in Maildir: \"" << fullfilename << "\": " << strerror(errno);
continue;
}
@@ -233,27 +224,26 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
bool ours = false;
for (; newIt != newMessages.end(); ++newIt) {
if ((filename == (*newIt).getUnique())
- && ((*newIt).getInternalFlags() & MaildirMessage::Committed)) {
+ && ((*newIt).getInternalFlags() & MaildirMessage::Committed))
+ {
ours = true;
break;
}
}
if (!ours && ::time(0) <= mystat.st_mtime) {
- old_cur_st_mtime = (time_t) 0;
- old_cur_st_ctime = (time_t) 0;
- old_new_st_mtime = (time_t) 0;
- old_new_st_ctime = (time_t) 0;
+ old_cur_st_mtime = (time_t)0;
+ old_cur_st_ctime = (time_t)0;
+ old_new_st_mtime = (time_t)0;
+ old_new_st_ctime = (time_t)0;
continue;
}
// move files from new/ to cur/
string newName = curpath + pdirent->d_name;
- if (rename((newpath + pdirent->d_name).c_str(),
- (newName + ":2,").c_str()) != 0) {
- bincWarning << "error moving messages from new to cur: skipping "
- << newpath
- << pdirent->d_name << ": " << strerror(errno) << endl;
+ if (rename((newpath + pdirent->d_name).c_str(), (newName + ":2,").c_str()) != 0) {
+ bincWarning << "error moving messages from new to cur: skipping " << newpath << pdirent->d_name
+ << ": " << strerror(errno) << endl;
continue;
}
}
@@ -263,8 +253,7 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
// Now, assume all known messages were expunged and have them prove
// otherwise.
{
- Mailbox::iterator i = begin(SequenceSet::all(),
- INCLUDE_EXPUNGED | SQNR_MODE);
+ Mailbox::iterator i = begin(SequenceSet::all(), INCLUDE_EXPUNGED | SQNR_MODE);
for (; i != end(); ++i)
(*i).setExpunged();
}
@@ -274,8 +263,8 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
if ((pdir = opendir(curpath.c_str())) == 0) {
string reason = "Maildir::scan::opendir(\"" + curpath + "\") == 0 (";
- reason += strerror(errno);
- reason += ")";
+ reason += strerror(errno);
+ reason += ")";
setLastError(reason);
return PermanentError;
@@ -299,22 +288,33 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
if ((pos = filename.find(':')) != string::npos) {
uniquename = filename.substr(0, pos);
string tmp = filename.substr(pos);
- if ((pos = tmp.find("2,")) != string::npos)
- standard = tmp.substr(pos + 2);
+ if ((pos = tmp.find("2,")) != string::npos) standard = tmp.substr(pos + 2);
} else
uniquename = filename;
unsigned char mflags = Message::F_NONE;
- for (string::const_iterator i = standard.begin();
- i != standard.end(); ++i) {
+ for (string::const_iterator i = standard.begin(); i != standard.end(); ++i) {
switch (*i) {
- case 'R': mflags |= Message::F_ANSWERED; break;
- case 'S': mflags |= Message::F_SEEN; break;
- case 'T': mflags |= Message::F_DELETED; break;
- case 'D': mflags |= Message::F_DRAFT; break;
- case 'F': mflags |= Message::F_FLAGGED; break;
- case 'P': mflags |= Message::F_PASSED; break;
- default: break;
+ case 'R':
+ mflags |= Message::F_ANSWERED;
+ break;
+ case 'S':
+ mflags |= Message::F_SEEN;
+ break;
+ case 'T':
+ mflags |= Message::F_DELETED;
+ break;
+ case 'D':
+ mflags |= Message::F_DRAFT;
+ break;
+ case 'F':
+ mflags |= Message::F_FLAGGED;
+ break;
+ case 'P':
+ mflags |= Message::F_PASSED;
+ break;
+ default:
+ break;
}
}
@@ -325,31 +325,31 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
if (stat(fullfilename.c_str(), &mystat) != 0) {
if (errno == ENOENT) {
// prevent looping due to stale symlinks
- if (lstat(fullfilename.c_str(), &mystat) == 0) {
- bincWarning << "dangling symlink: " << fullfilename << endl;
+ if (lstat(fullfilename.c_str(), &mystat) == 0) {
+ bincWarning << "dangling symlink: " << fullfilename << endl;
continue;
}
- // a rare race between readdir and stat force us to restart
- // the scan.
+ // a rare race between readdir and stat force us to restart
+ // the scan.
index.clearFileNames();
closedir(pdir);
if ((pdir = opendir(newpath.c_str())) == 0) {
string reason = "Warning: opendir(\"" + newpath + "\") == 0 (";
- reason += strerror(errno);
- reason += ")";
+ reason += strerror(errno);
+ reason += ")";
setLastError(reason);
return PermanentError;
}
}
-
+
continue;
}
mailboxchanged = true;
}
-
+
index.insert(uniquename, 0, filename);
// If we have this message in memory already..
@@ -382,7 +382,7 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
m.setInternalDate(mystat.st_mtime);
m.setStdFlag((mflags | Message::F_RECENT) & ~Message::F_EXPUNGED);
m.setUnique(uniquename);
- tempMessageMap.insert(make_pair((unsigned int) mystat.st_mtime, m));
+ tempMessageMap.insert(make_pair((unsigned int)mystat.st_mtime, m));
mailboxchanged = true;
}
@@ -432,8 +432,7 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
if (firstscan) {
unsigned int lastuid = 0;
- Mailbox::iterator ii
- = begin(SequenceSet::all(), INCLUDE_EXPUNGED | SQNR_MODE);
+ Mailbox::iterator ii = begin(SequenceSet::all(), INCLUDE_EXPUNGED | SQNR_MODE);
for (; ii != end(); ++ii) {
MaildirMessage &message = (MaildirMessage &)*ii;
message.clearInternalFlag(MaildirMessage::JustArrived);
@@ -442,19 +441,19 @@ Maildir::ScanResult Maildir::scan(bool forceScan)
lastuid = message.getUID();
else {
bincWarning << "UID values are not strictly ascending in this"
- " mailbox: " << path << ". This is usually caused by "
- << "access from a broken accessor. Bumping UIDVALIDITY."
- << endl;
+ " mailbox: "
+ << path << ". This is usually caused by "
+ << "access from a broken accessor. Bumping UIDVALIDITY." << endl;
setLastError("An error occurred while scanning the mailbox. "
"Please contact your system administrator.");
if (!readOnly) {
bumpUidValidity(path);
- old_cur_st_mtime = (time_t) 0;
- old_cur_st_ctime = (time_t) 0;
- old_new_st_mtime = (time_t) 0;
- old_new_st_ctime = (time_t) 0;
+ old_cur_st_mtime = (time_t)0;
+ old_cur_st_ctime = (time_t)0;
+ old_new_st_mtime = (time_t)0;
+ old_new_st_ctime = (time_t)0;
return TemporaryError;
} else {
return PermanentError;