diff options
Diffstat (limited to 'src/maildir-writecache.cc')
-rw-r--r-- | src/maildir-writecache.cc | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/maildir-writecache.cc b/src/maildir-writecache.cc new file mode 100644 index 0000000..feda4bd --- /dev/null +++ b/src/maildir-writecache.cc @@ -0,0 +1,74 @@ +/** -------------------------------------------------------------------- + * @file maildir-writecache.cc + * @brief Implementation of the Maildir class. + * @author Andreas Aardal Hanssen + * @date 2002-2005 + * ------------------------------------------------------------------ **/ +#include <dirent.h> +#include <fcntl.h> +#include <unistd.h> + +#include "globals.h" +#include "maildir.h" + +using namespace ::std; + +//------------------------------------------------------------------------ +bool Binc::Maildir::writeCache(void) +{ + if (readOnly) + return true; + + char *safename = strdup((path + "/.bincimap-cache-tmp-XXXXXX").c_str()); + int fd = mkstemp(safename); + if (!fd) { + free(safename); + return false; + } + + 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(0); + 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()); + vector<string> cflags = message.getCustomFlags(); + for (vector<string>::const_iterator it = cflags.begin(); + it != cflags.end(); ++it) { + 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; +} |