/** * @file maildir-readcache.cc * @brief Implementation of the Maildir class. * @author Andreas Aardal Hanssen * @date 2002-2005 */ #include "convert.h" #include "globals.h" #include "maildir.h" #include using namespace Binc; using std::string; using std::vector; Maildir::ReadCacheResult Maildir::readCache(void) { index.clearUids(); const string cachefilename = path + "/bincimap-cache"; FILE *fp = fopen(cachefilename.c_str(), "r"); if (!fp) { uidvalidity = time(nullptr); uidnext = 1; messages.clear(); index.clear(); newMessages.clear(); return NoCache; } char inputBuffer[512]; if (!fgets(inputBuffer, sizeof(inputBuffer), fp)) { fclose(fp); uidvalidity = time(nullptr); 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(nullptr); 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(nullptr); uidnext = 1; messages.clear(); index.clear(); newMessages.clear(); return NoCache; } vector customFlags; char *flagStart = inputBuffer; for (int i = 0; flagStart != nullptr && *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) == nullptr) { for (auto tmpFlag : customFlags) { 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 oldCustomFlags = existingMessage.getCustomFlags(); sort(oldCustomFlags.begin(), oldCustomFlags.end()); sort(customFlags.begin(), customFlags.end()); if (oldCustomFlags != customFlags) { existingMessage.resetCustomFlags(); for (auto tmpFlag : customFlags) { trim(tmpFlag, " \n"); existingMessage.setCustomFlag(tmpFlag); } } } } fclose(fp); return Ok; }