summaryrefslogtreecommitdiff
path: root/src/maildir-readcache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/maildir-readcache.cc')
-rw-r--r--src/maildir-readcache.cc151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/maildir-readcache.cc b/src/maildir-readcache.cc
new file mode 100644
index 0000000..a108242
--- /dev/null
+++ b/src/maildir-readcache.cc
@@ -0,0 +1,151 @@
+/** --------------------------------------------------------------------
+ * @file maildir-readcache.cc
+ * @brief Implementation of the Maildir class.
+ * @author Andreas Aardal Hanssen
+ * @date 2002-2005
+ * ----------------------------------------------------------------- **/
+#include <algorithm>
+#include "maildir.h"
+#include "convert.h"
+#include "globals.h"
+
+using namespace ::std;
+using namespace Binc;
+
+//------------------------------------------------------------------------
+Maildir::ReadCacheResult Maildir::readCache(void)
+{
+ index.clearUids();
+
+ const string cachefilename = path + "/bincimap-cache";
+ FILE *fp = fopen(cachefilename.c_str(), "r");
+ if (!fp) {
+ uidvalidity = time(0);
+ uidnext = 1;
+ messages.clear();
+ index.clear();
+ newMessages.clear();
+ return NoCache;
+ }
+
+ char inputBuffer[512];
+ if (!fgets(inputBuffer, sizeof(inputBuffer), fp)) {
+ fclose(fp);
+ uidvalidity = time(0);
+ uidnext = 1;
+ messages.clear();
+ index.clear();
+ newMessages.clear();
+ return NoCache;
+ }
+
+ // terminate the buffer
+ inputBuffer[sizeof(inputBuffer) - 1] = '\0';
+
+ char cacheFileVersionBuffer[512];
+ unsigned int readUidValidity;
+ unsigned int readUidNext;
+
+ if (sscanf(inputBuffer, "%s %u %u", cacheFileVersionBuffer, &readUidValidity, &readUidNext) != 3
+ || strcmp(cacheFileVersionBuffer, BINC_CACHE) != 0) {
+ // bump cache
+ fclose(fp);
+ uidvalidity = time(0);
+ uidnext = 1;
+ messages.clear();
+ index.clear();
+ newMessages.clear();
+ return NoCache;
+ }
+
+ uidnext = readUidNext;
+ uidvalidity = readUidValidity;
+
+ unsigned int readUID;
+ unsigned int readSize;
+ unsigned int readInternalDate;
+ char readUnique[512];
+
+ while (fgets(inputBuffer, sizeof(inputBuffer), fp)) {
+ inputBuffer[sizeof(inputBuffer) - 1] = '\0';
+ if (sscanf(inputBuffer, "%u %u %u %s", &readUID,
+ &readInternalDate, &readSize, readUnique) != 4) {
+ // error in input
+ fclose(fp);
+ uidvalidity = time(0);
+ uidnext = 1;
+ messages.clear();
+ index.clear();
+ newMessages.clear();
+ return NoCache;
+ }
+
+ vector<string> customFlags;
+
+ char *flagStart = inputBuffer;
+ for (int i = 0; flagStart != 0 && *flagStart != '\0' && i < 4; ++i) {
+ flagStart = strchr(flagStart, ' ');
+
+ // skip consecutive white space
+ while (flagStart && *flagStart == ' ')
+ ++flagStart;
+ }
+
+ // get flags
+ while (flagStart) {
+ char *lastOffset = flagStart;
+ flagStart = strchr(flagStart, ' ');
+ if (flagStart) {
+ *flagStart = '\0';
+ ++flagStart;
+ }
+
+ customFlags.push_back(lastOffset);
+
+ // skip consecutive white space
+ while (flagStart && *flagStart != '\0' && *flagStart == ' ')
+ ++flagStart;
+ }
+
+ MaildirMessage m(*this);
+ m.setUnique(readUnique);
+ m.setInternalDate(readInternalDate);
+
+ if (index.find(readUnique) == 0) {
+ for (vector<string>::const_iterator it = customFlags.begin();
+ it != customFlags.end(); ++it) {
+ string tmpFlag = *it;
+ trim(tmpFlag, " \n");
+ m.setCustomFlag(tmpFlag);
+ }
+
+ m.setUID(readUID);
+ m.setInternalFlag(MaildirMessage::JustArrived);
+ m.setSize(readSize);
+ add(m);
+ } else {
+ // Remember to insert the uid of the message again - we reset this
+ // at the top of this function.
+ index.insert(readUnique, readUID);
+ MaildirMessage &existingMessage = messages.find(readUID)->second;
+
+ vector<string> oldCustomFlags = existingMessage.getCustomFlags();
+ sort(oldCustomFlags.begin(), oldCustomFlags.end());
+ sort(customFlags.begin(), customFlags.end());
+ if (oldCustomFlags != customFlags) {
+ existingMessage.resetCustomFlags();
+ for (vector<string>::const_iterator it = customFlags.begin();
+ it != customFlags.end(); ++it) {
+ string tmpFlag = *it;
+ trim(tmpFlag, " \n");
+ existingMessage.setCustomFlag(tmpFlag);
+ }
+ }
+ }
+ }
+
+ fclose(fp);
+
+ return Ok;
+}
+