summaryrefslogtreecommitdiff
path: root/src/maildir.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/maildir.cc')
-rw-r--r--src/maildir.cc168
1 files changed, 58 insertions, 110 deletions
diff --git a/src/maildir.cc b/src/maildir.cc
index 5071a1a..dc7e45a 100644
--- a/src/maildir.cc
+++ b/src/maildir.cc
@@ -1,9 +1,10 @@
-/** --------------------------------------------------------------------
+/**
* @file maildir.cc
* @brief Implementation of the Maildir class.
* @author Andreas Aardal Hanssen
* @date 2002-2005
- * ----------------------------------------------------------------- **/
+ */
+
#include "maildir.h"
#include "convert.h"
@@ -30,16 +31,16 @@
#include <sys/types.h>
#include <unistd.h>
-using namespace ::std;
using namespace Binc;
+using std::endl;
+using std::map;
+using std::string;
// Used to generate the unique names for Maildir delivery
static int numDeliveries = 0;
-//------------------------------------------------------------------------
Maildir::iterator::iterator(void) {}
-//------------------------------------------------------------------------
Maildir::iterator::iterator(Maildir *home,
MessageMap::iterator it,
const SequenceSet &_bset,
@@ -54,7 +55,6 @@ Maildir::iterator::iterator(Maildir *home,
sqnrmax = home->getMaxSqnr();
}
-//------------------------------------------------------------------------
Maildir::iterator::iterator(const iterator &copy)
: BaseIterator(copy.sqnr)
, mailbox(copy.mailbox)
@@ -65,7 +65,6 @@ Maildir::iterator::iterator(const iterator &copy)
, sqnrmax(copy.sqnrmax)
{}
-//------------------------------------------------------------------------
Maildir::iterator &Maildir::iterator::operator=(const iterator &copy)
{
sqnr = copy.sqnr;
@@ -78,22 +77,18 @@ Maildir::iterator &Maildir::iterator::operator=(const iterator &copy)
return *this;
}
-//------------------------------------------------------------------------
Maildir::iterator::~iterator(void) {}
-//------------------------------------------------------------------------
MaildirMessage &Maildir::iterator::curMessage(void)
{
return i->second;
}
-//------------------------------------------------------------------------
Message &Maildir::iterator::operator*(void)
{
return curMessage();
}
-//------------------------------------------------------------------------
void Maildir::iterator::operator++(void)
{
++i;
@@ -101,20 +96,17 @@ void Maildir::iterator::operator++(void)
reposition();
}
-//------------------------------------------------------------------------
bool Maildir::iterator::operator==(const BaseIterator &a) const
{
const iterator *b = dynamic_cast<const iterator *>(&a);
return b ? (i == b->i) : false;
}
-//------------------------------------------------------------------------
bool Maildir::iterator::operator!=(const BaseIterator &a) const
{
return !((*this) == a);
}
-//------------------------------------------------------------------------
void Maildir::iterator::reposition(void)
{
for (;;) {
@@ -144,23 +136,20 @@ void Maildir::iterator::reposition(void)
}
}
-//------------------------------------------------------------------------
Mailbox::iterator Maildir::begin(const SequenceSet &bset, unsigned int mod) const
{
- beginIterator = iterator((Maildir *)this, messages.begin(), bset, mod);
+ beginIterator = iterator(const_cast<Maildir *>(this), messages.begin(), bset, mod);
beginIterator.reposition();
return Mailbox::iterator(beginIterator);
}
-//------------------------------------------------------------------------
Mailbox::iterator Maildir::end(void) const
{
- endIterator = iterator((Maildir *)this, messages.end(), endIterator.bset, endIterator.mod);
+ endIterator = iterator(const_cast<Maildir *>(this), messages.end(), endIterator.bset, endIterator.mod);
return Mailbox::iterator(endIterator);
}
-//------------------------------------------------------------------------
void Maildir::iterator::erase(void)
{
MessageMap::iterator iter = i;
@@ -174,7 +163,6 @@ void Maildir::iterator::erase(void)
reposition();
}
-//------------------------------------------------------------------------
Maildir::Maildir(void) : Mailbox()
{
firstscan = true;
@@ -186,16 +174,13 @@ Maildir::Maildir(void) : Mailbox()
oldexists = 0;
}
-//------------------------------------------------------------------------
Maildir::~Maildir(void) {}
-//------------------------------------------------------------------------
void Maildir::setPath(const string &path_in)
{
path = path_in;
}
-//------------------------------------------------------------------------
bool Maildir::getUpdates(bool doscan, unsigned int type, PendingUpdates &updates, bool forceScan)
{
if (doscan && scan(forceScan) != Success) return false;
@@ -216,8 +201,9 @@ bool Maildir::getUpdates(bool doscan, unsigned int type, PendingUpdates &updates
i.erase();
mailboxchanged = true;
displayExists = true;
- } else
+ } else {
++i;
+ }
}
}
@@ -250,7 +236,6 @@ bool Maildir::getUpdates(bool doscan, unsigned int type, PendingUpdates &updates
return true;
}
-//------------------------------------------------------------------------
bool Maildir::isMailbox(const std::string &s_in) const
{
struct stat mystat;
@@ -260,27 +245,24 @@ bool Maildir::isMailbox(const std::string &s_in) const
&& (stat((s_in + "/tmp").c_str(), &mystat) == 0 && S_ISDIR(mystat.st_mode)));
}
-//------------------------------------------------------------------------
const std::string Maildir::getTypeName(void) const
{
return "Maildir";
}
-//------------------------------------------------------------------------
void Maildir::bumpUidValidity(const string &s_in) const
{
unlink((s_in + "/bincimap-uidvalidity").c_str());
unlink((s_in + "/bincimap-cache").c_str());
}
-//------------------------------------------------------------------------
bool Maildir::isMarked(const std::string &s_in) const
{
DIR *dirp = opendir((s_in + "/new").c_str());
- if (dirp == 0) return false;
+ if (dirp == nullptr) return false;
struct dirent *direntp;
- while ((direntp = readdir(dirp)) != 0) {
+ while ((direntp = readdir(dirp)) != nullptr) {
string s = direntp->d_name;
if (s[0] != '.' && s.find('/') == string::npos && s.find(':') == string::npos) {
closedir(dirp);
@@ -292,7 +274,6 @@ bool Maildir::isMarked(const std::string &s_in) const
return false;
}
-//------------------------------------------------------------------------
unsigned int Maildir::getStatusID(const string &path) const
{
unsigned int statusid = 0;
@@ -306,7 +287,6 @@ unsigned int Maildir::getStatusID(const string &path) const
return statusid;
}
-//------------------------------------------------------------------------
bool Maildir::getStatus(const string &path, Status &s) const
{
unsigned int messages = 0;
@@ -319,8 +299,8 @@ bool Maildir::getStatus(const string &path, Status &s) const
const string cachefilename = path + "/bincimap-cache";
FILE *fp = fopen(cachefilename.c_str(), "r");
- if (fp) do
- {
+ if (fp) {
+ do {
char inputBuffer[512];
if (!fgets(inputBuffer, sizeof(inputBuffer), fp)) {
fclose(fp);
@@ -362,18 +342,18 @@ bool Maildir::getStatus(const string &path, Status &s) const
fclose(fp);
- s.setUidValidity(readUidValidity < 1 ? time(0) : readUidValidity);
+ s.setUidValidity(readUidValidity < 1 ? time(nullptr) : readUidValidity);
} while (0);
- else {
- s.setUidValidity(time(0));
+ } else {
+ s.setUidValidity(time(nullptr));
}
// Scan new
DIR *dirp = opendir((path + "/new").c_str());
- if (dirp == 0) return false;
+ if (dirp == nullptr) return false;
struct dirent *direntp;
- while ((direntp = readdir(dirp)) != 0) {
+ while ((direntp = readdir(dirp)) != nullptr) {
const string filename = direntp->d_name;
if (filename[0] == '.' || filename.find(':') != string::npos || filename.find('/') != string::npos)
continue;
@@ -387,9 +367,9 @@ bool Maildir::getStatus(const string &path, Status &s) const
closedir(dirp);
// Scan cur
- if ((dirp = opendir((path + "/cur").c_str())) == 0) return false;
+ if ((dirp = opendir((path + "/cur").c_str())) == nullptr) return false;
- while ((direntp = readdir(dirp)) != 0) {
+ while ((direntp = readdir(dirp)) != nullptr) {
const string dname = direntp->d_name;
if (dname[0] == '.') continue;
@@ -425,7 +405,6 @@ bool Maildir::getStatus(const string &path, Status &s) const
return true;
}
-//------------------------------------------------------------------------
unsigned int Maildir::getMaxUid(void) const
{
MessageMap::const_iterator i = messages.end();
@@ -445,7 +424,6 @@ unsigned int Maildir::getMaxUid(void) const
return 0;
}
-//------------------------------------------------------------------------
unsigned int Maildir::getMaxSqnr(void) const
{
int sqnr = messages.size();
@@ -467,51 +445,41 @@ unsigned int Maildir::getMaxSqnr(void) const
return 0;
}
-//------------------------------------------------------------------------
unsigned int Maildir::getUidValidity(void) const
{
return uidvalidity;
}
-//------------------------------------------------------------------------
unsigned int Maildir::getUidNext(void) const
{
return uidnext;
}
-//------------------------------------------------------------------------
Message *Maildir::createMessage(const string &mbox, time_t idate)
{
string sname = mbox + "/tmp/bincimap-XXXXXX";
- char *safename = strdup(sname.c_str());
- int fd = mkstemp(safename);
+ int fd = mkstemp(sname.data());
if (fd == -1) {
setLastError("Unable to create safe name.");
- return 0;
+ return nullptr;
}
- string safenameStr = safename;
- delete[] safename;
-
MaildirMessage message(*this);
message.setFile(fd);
- message.setSafeName(safenameStr);
+ message.setSafeName(sname);
message.setInternalDate(idate);
newMessages.push_back(message);
- vector<MaildirMessage>::iterator i = newMessages.end();
- --i;
- return &(*i);
+ return &newMessages.back();
}
-//------------------------------------------------------------------------
bool Maildir::commitNewMessages(const string &mbox)
{
Session &session = Session::getInstance();
- vector<MaildirMessage>::iterator i = newMessages.begin();
+ std::vector<MaildirMessage>::iterator i = newMessages.begin();
map<MaildirMessage *, string> committedMessages;
struct timeval youngestFile = {0, 0};
@@ -531,13 +499,13 @@ bool Maildir::commitNewMessages(const string &mbox)
for (int attempt = 0; !abort && attempt < 1000; ++attempt) {
struct timeval tv;
- gettimeofday(&tv, 0);
+ gettimeofday(&tv, nullptr);
youngestFile = tv;
// Generate Maildir conformant file name
BincStream ssid;
ssid << (int)tv.tv_sec << "."
- << "R" << (int)rand() << "M" << (int)tv.tv_usec << "P" << (int)session.getPid() << "Q"
+ << "R" << rand() << "M" << (int)tv.tv_usec << "P" << session.getPid() << "Q"
<< numDeliveries++ << "." << session.getEnv("TCPLOCALHOST");
BincStream ss;
@@ -568,33 +536,29 @@ bool Maildir::commitNewMessages(const string &mbox)
++i;
}
- // abort means to make an attempt to restore the mailbox to
- // its original state.
+ // abort means to make an attempt to restore the mailbox to its original state.
if (abort) {
// Fixme: Messages that are in committedMessages should be skipped
// here.
- for (i = newMessages.begin(); i != newMessages.end(); ++i)
- unlink((*i).getSafeName().c_str());
+ for (const auto &i : newMessages)
+ unlink(i.getSafeName().c_str());
- map<MaildirMessage *, string>::const_iterator j = committedMessages.begin();
- while (j != committedMessages.end()) {
- if (unlink(j->second.c_str()) != 0) {
+ for (const auto &[_, second] : committedMessages) {
+ if (unlink(second.c_str()) != 0) {
if (errno == ENOENT) {
// FIXME: The message was probably moves away from new/ by
// another IMAP session.
bincWarning << "error rollbacking after failed commit to " << toImapString(mbox)
- << ", failed to unlink " << toImapString(j->second) << ": " << strerror(errno)
+ << ", failed to unlink " << toImapString(second) << ": " << strerror(errno)
<< endl;
} else {
bincWarning << "error rollbacking after failed commit to " << toImapString(mbox)
- << ", failed to unlink " << toImapString(j->second) << ": " << strerror(errno)
+ << ", failed to unlink " << toImapString(second) << ": " << strerror(errno)
<< endl;
newMessages.clear();
return false;
}
}
-
- ++j;
}
newMessages.clear();
@@ -606,16 +570,14 @@ bool Maildir::commitNewMessages(const string &mbox)
// random number by spinning until the timestamp has changed before
// moving the message into cur.
struct timeval tv;
- gettimeofday(&tv, 0);
- while (tv.tv_sec == youngestFile.tv_sec && tv.tv_usec == youngestFile.tv_usec) {
- gettimeofday(&tv, 0);
- }
+ gettimeofday(&tv, nullptr);
+ while (tv.tv_sec == youngestFile.tv_sec && tv.tv_usec == youngestFile.tv_usec)
+ gettimeofday(&tv, nullptr);
- map<MaildirMessage *, string>::const_iterator j = committedMessages.begin();
- for (; j != committedMessages.end(); ++j) {
- string basename = j->second.substr(j->second.rfind('/') + 1);
+ for (auto &j : committedMessages) {
+ string basename = j.second.substr(j.second.rfind('/') + 1);
- int flags = j->first->getStdFlags();
+ int flags = j.first->getStdFlags();
string flagStr;
if (flags & Message::F_DRAFT) flagStr += "D";
if (flags & Message::F_FLAGGED) flagStr += "F";
@@ -624,30 +586,27 @@ bool Maildir::commitNewMessages(const string &mbox)
if (flags & Message::F_DELETED) flagStr += "T";
string dest = mbox + "/cur/" + basename + ":2," + flagStr;
- if (rename(j->second.c_str(), dest.c_str()) == 0) continue;
+ if (rename(j.second.c_str(), dest.c_str()) == 0) continue;
- if (errno != ENOENT)
- bincWarning << "when setting flags on: " << j->second << ": " << strerror(errno) << endl;
+ if (errno != ENOENT) {
+ bincWarning << "when setting flags on: " << j.second << ": " << strerror(errno) << endl;
+ }
}
committedMessages.clear();
return true;
}
-//------------------------------------------------------------------------
bool Maildir::rollBackNewMessages(void)
{
- vector<MaildirMessage>::const_iterator i = newMessages.begin();
- // Fixme: Messages that are in committedMessages should be skipped
- // here.
- for (; i != newMessages.end(); ++i)
- unlink((*i).getSafeName().c_str());
+ // Fixme: Messages that are in committedMessages should be skipped here.
+ for (const auto &i : newMessages)
+ unlink(i.getSafeName().c_str());
newMessages.clear();
return true;
}
-//------------------------------------------------------------------------
bool Maildir::fastCopy(Message &m, Mailbox &desttype, const std::string &destname)
{
// At this point, fastCopy is broken because the creation time is
@@ -669,7 +628,7 @@ bool Maildir::fastCopy(Message &m, Mailbox &desttype, const std::string &destnam
for (int attempt = 0; attempt < 1000; ++attempt) {
struct timeval tv;
- gettimeofday(&tv, 0);
+ gettimeofday(&tv, nullptr);
// Generate Maildir conformant file name
BincStream ssid;
@@ -686,7 +645,7 @@ bool Maildir::fastCopy(Message &m, Mailbox &desttype, const std::string &destnam
MaildirMessage newmess = *message;
newmess.setSafeName(fileName);
newmess.setUnique(ssid.str());
- newmess.setInternalDate((time_t)tv.tv_sec);
+ newmess.setInternalDate(tv.tv_sec);
newmess.setUID(0);
newMessages.push_back(newmess);
break;
@@ -705,34 +664,30 @@ bool Maildir::fastCopy(Message &m, Mailbox &desttype, const std::string &destnam
return true;
}
-//------------------------------------------------------------------------
MaildirMessage *Maildir::get(const std::string &id)
{
MaildirIndexItem *item = index.find(id);
- if (!item) return 0;
+ if (!item) return nullptr;
unsigned int uid = item->uid;
- if (messages.find(uid) == messages.end()) return 0;
+ if (messages.find(uid) == messages.end()) return nullptr;
return &messages.find(uid)->second;
}
-//------------------------------------------------------------------------
void Maildir::add(MaildirMessage &m)
{
MessageMap::iterator it = messages.find(m.getUID());
if (it != messages.end()) messages.erase(it);
- messages.insert(make_pair(m.getUID(), m));
+ messages.insert(std::make_pair(m.getUID(), m));
index.insert(m.getUnique(), m.getUID());
}
-//------------------------------------------------------------------------
unsigned int MaildirIndex::getSize(void) const
{
return idx.size();
}
-//------------------------------------------------------------------------
void MaildirIndex::insert(const string &unique, unsigned int uid, const string &fileName)
{
if (idx.find(unique) == idx.end()) {
@@ -747,40 +702,33 @@ void MaildirIndex::insert(const string &unique, unsigned int uid, const string &
}
}
-//------------------------------------------------------------------------
void MaildirIndex::remove(const string &unique)
{
map<string, MaildirIndexItem>::iterator it = idx.find(unique);
if (it != idx.end()) idx.erase(it);
}
-//------------------------------------------------------------------------
MaildirIndexItem *MaildirIndex::find(const string &unique)
{
map<string, MaildirIndexItem>::iterator it = idx.find(unique);
if (it != idx.end()) return &it->second;
- return 0;
+ return nullptr;
}
-//------------------------------------------------------------------------
void MaildirIndex::clear(void)
{
idx.clear();
}
-//------------------------------------------------------------------------
void MaildirIndex::clearUids(void)
{
- map<string, MaildirIndexItem>::iterator it = idx.begin();
- for (; it != idx.end(); ++it)
- it->second.uid = 0;
+ for (auto &it : idx)
+ it.second.uid = 0;
}
-//------------------------------------------------------------------------
void MaildirIndex::clearFileNames(void)
{
- map<string, MaildirIndexItem>::iterator it = idx.begin();
- for (; it != idx.end(); ++it)
- it->second.fileName = "";
+ for (auto &it : idx)
+ it.second.fileName = "";
}