Bincimap 2.0.16
Easy Imapping
Loading...
Searching...
No Matches
maildir-updateflags.cc
Go to the documentation of this file.
1
7#include "maildir.h"
8
9#include <dirent.h>
10#include <unistd.h>
11#include <errno.h>
12
13#include "iodevice.h"
14#include "iofactory.h"
15
16using namespace ::std;
17
18//------------------------------------------------------------------------
20{
21 // don't update a read-only mailbox.
22 if (readOnly) return;
23
24 // open the cur/ directory
25 string curpath = path + "/cur/";
26 DIR *pdir = opendir(curpath.c_str());
27 if (pdir == 0) {
28 bincError << "failed to open " << curpath << ": "
29 << strerror(errno) << endl;
30 return;
31 }
32
33 // read all entries in the directory
34 vector<string> entries;
35 struct dirent *pdirent;
36 while ((pdirent = readdir(pdir)) != 0) {
37 string filename = pdirent->d_name;
38 if (filename[0] == '.')
39 continue;
40 entries.push_back(filename);
41 }
42 closedir(pdir);
43
44 bool customFlagsChanged = false;
45
46 // loop through all messages in cur/, and update the flags that have
47 // changed.
48 for (vector<string>::const_iterator it = entries.begin(); it != entries.end(); ++it) {
49 string filename = *it;
50
51 // separate the unique name from the flags. accept messages that do not
52 // contain the flags section.
53 string uniquename;
54 string::size_type pos;
55 if ((pos = filename.find(":2,")) != string::npos)
56 uniquename = filename.substr(0, pos);
57 else
58 uniquename = filename;
59
60 // only update flags for messages that are known.
61 MaildirMessage *message = get(uniquename);
62 if (!message)
63 continue;
64
65 // check if custom flags have changed; if so, we need to regenerate the
66 // cache file.
67 if (message->internalFlags & MaildirMessage::CustomFlagsChanged)
68 customFlagsChanged = true;
69
70 // generate the flag string.
71 string flags;
72 int mflags = message->getStdFlags();
73 if (mflags & Message::F_DRAFT) flags += "D";
74 if (mflags & Message::F_FLAGGED) flags += "F";
75 if (mflags & Message::F_PASSED) flags += "P";
76 if (mflags & Message::F_ANSWERED) flags += "R";
77 if (mflags & Message::F_SEEN) flags += "S";
78 if (mflags & Message::F_DELETED) flags += "T";
79
80 // prepare the old and new message name. if equal, skip to the next
81 // message.
82 string srcname = curpath + filename;
83 string destname = curpath + uniquename + ":2," + flags;
84 if (srcname == destname)
85 continue;
86
87 // rename the file
88 if (rename(srcname.c_str(), destname.c_str()) != 0) {
89 if (errno == ENOENT) {
90 closedir(pdir);
91 if ((pdir = opendir(curpath.c_str())) == 0) {
92 bincError << "failed to open " << curpath << ": "
93 << strerror(errno) << endl;
94 return;
95 }
96
97 // restart scan. this catches the race condition where concurrent
98 // clients may have set a flag or removed the message.
99 continue;
100 }
101
102 bincError << "failed to rename " << srcname
103 << " to " << destname << ": "
104 << strerror(errno) << endl;
105 } else {
106 index.insert(uniquename, 0, uniquename + ":2," + flags);
107 }
108 }
109
110 // finally, regenerate the cache file if the custom flags have changed.
111 if (customFlagsChanged) {
112 Lock lock(path);
113 writeCache();
114 }
115}
bool readOnly
Definition: mailbox.h:125
bool writeCache(void)
void updateFlags(void)
MaildirMessage * get(const std::string &id)
Definition: maildir.cc:756
void insert(const std::string &unique, unsigned int uid, const std::string &fileName="")
Definition: maildir.cc:786
The MaildirMessage class provides an interface for IMAP messages.
unsigned char getStdFlags(void) const
Declaration of the IODevice class.
Declaration of the IOFactory class.
#define bincError
Definition: iofactory.h:42
Declaration of the Maildir class.