/** * @file maildir-writecache.cc * @brief Implementation of the Maildir class. * @author Andreas Aardal Hanssen * @date 2002-2005 */ #include "globals.h" #include "maildir.h" #include #include #include bool Binc::Maildir::writeCache() { if (readOnly) return true; char *safename = strdup((path + "/.bincimap-cache-tmp-XXXXXX").c_str()); int fd = mkstemp(safename); if (!fd) { free(safename); return false; } std::string safeName = safename; free(safename); FILE *fp = fdopen(fd, "w"); if (!fp) { unlink(safeName.c_str()); return false; } if (uidvalidity == 0 || uidnext == 0) { uidvalidity = time(nullptr); uidnext = messages.size() + 1; } fprintf(fp, "%s %u %u\n", BINC_CACHE, uidvalidity, uidnext); Mailbox::iterator i = begin(SequenceSet::all(), INCLUDE_EXPUNGED); for (; i != end(); ++i) { MaildirMessage &message = (MaildirMessage &)*i; fprintf(fp, "%u %u %u %s", message.getUID(), (unsigned int)message.getInternalDate(), message.getSize(), message.getUnique().c_str()); std::vector cflags = message.getCustomFlags(); for (const auto &it : cflags) fprintf(fp, " %s", it.c_str()); fprintf(fp, "\n"); } if (fflush(fp) || (fsync(fd) && (errno != EROFS || errno != EINVAL)) || fclose(fp)) { unlink(safeName.c_str()); return false; } if (rename(safeName.c_str(), (path + "/bincimap-cache").c_str()) != 0) { unlink(safeName.c_str()); return false; } int dfd = open(path.c_str(), O_RDONLY); if (dfd == -1 || (fsync(fd) && (errno != EROFS || errno != EINVAL)) || close(dfd)) return false; return true; }