maildir-index.c revision db1ee4a91a6572602302115e02146b29adea3a54
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen#include "lib.h"
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen#include "ioloop.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "hash.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "hostpid.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "str.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "maildir-index.h"
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen#include "mail-index-data.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "mail-index-util.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen#include <stdio.h>
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen#include <sys/stat.h>
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include <sys/time.h>
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include <time.h>
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenextern struct mail_index maildir_index;
53dfcefa9440a49d703e49193819a79be99c9ba6Timo Sirainen
f0d93763f210ecdb85a115fdd0210a16cfc5ff5cTimo Sirainenstatic int maildir_index_open(struct mail_index *index,
53dfcefa9440a49d703e49193819a79be99c9ba6Timo Sirainen enum mail_index_open_flags flags)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen maildir_clean_tmp(t_strconcat(index->mailbox_path, "/tmp", NULL));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return mail_index_open(index, flags);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenconst char *maildir_get_location(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
2e78f05b11df23ec2731afaf8f19d5b5240cb29fTimo Sirainen const char *fname, *new_fname;
2e78f05b11df23ec2731afaf8f19d5b5240cb29fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen fname = index->lookup_field(index, rec, DATA_FIELD_LOCATION);
d1e7425048c61d71f41f737ba947687198842dc2Timo Sirainen if (fname == NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen index_data_set_corrupted(index->data,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "Missing location field for record %u", rec->uid);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (index->new_filenames != NULL) {
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen new_fname = hash_lookup(index->new_filenames, fname);
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen if (new_fname != NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return new_fname;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return fname;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen}
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenconst char *maildir_generate_tmp_filename(const struct timeval *tv)
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen{
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen static unsigned int create_count = 0;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return t_strdup_printf("%s.P%sQ%uM%s.%s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen dec2str(tv->tv_sec), my_pid, create_count++,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen dec2str(tv->tv_usec), my_hostname);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint maildir_create_tmp(struct mail_index *index, const char *dir,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char **fname)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen{
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen const char *path, *tmp_fname;
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen struct stat st;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct timeval *tv, tv_now;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen pool_t pool;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int fd;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen tv = &ioloop_timeval;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen pool = pool_alloconly_create("maildir_tmp", 4096);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (;;) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen p_clear(pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen tmp_fname = maildir_generate_tmp_filename(tv);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen path = p_strconcat(pool, dir, "/", tmp_fname, NULL);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (stat(path, &st) < 0 && errno == ENOENT) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* doesn't exist */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (fd != -1 || errno != EEXIST)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen break;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* wait and try again - very unlikely */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen sleep(2);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen tv = &tv_now;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (gettimeofday(&tv_now, NULL) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_fatal("gettimeofday(): %m");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen *fname = t_strdup(path);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (fd == -1)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen index_file_set_syscall_error(index, path, "open()");
ca843e046e98b12f4730f4b87ee2e1a659c26e78Timo Sirainen
ca843e046e98b12f4730f4b87ee2e1a659c26e78Timo Sirainen pool_unref(pool);
ca843e046e98b12f4730f4b87ee2e1a659c26e78Timo Sirainen return fd;
ca843e046e98b12f4730f4b87ee2e1a659c26e78Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenenum mail_flags maildir_filename_get_flags(const char *fname,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_flags default_flags)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e7dd5065d21c569e5e6ddd713bd345dadd1cf51dTimo Sirainen const char *info;
e7dd5065d21c569e5e6ddd713bd345dadd1cf51dTimo Sirainen enum mail_flags flags;
d694a52bce62c52080c3f87a56dcf77030fd2712Timo Sirainen
d694a52bce62c52080c3f87a56dcf77030fd2712Timo Sirainen info = strchr(fname, ':');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (info == NULL || info[1] != '2' || info[2] != ',')
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return default_flags;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen flags = 0;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (info += 3; *info != '\0' && *info != ','; info++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen switch (*info) {
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen case 'R': /* replied */
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen flags |= MAIL_ANSWERED;
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen break;
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen case 'S': /* seen */
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen flags |= MAIL_SEEN;
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen break;
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen case 'T': /* trashed */
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen flags |= MAIL_DELETED;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen break;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen case 'D': /* draft */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen flags |= MAIL_DRAFT;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen break;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen case 'F': /* flagged */
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen flags |= MAIL_FLAGGED;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen break;
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen default:
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (*info >= 'a' && *info <= 'z') {
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen /* custom flag */
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen flags |= 1 << (MAIL_CUSTOM_FLAG_1_BIT +
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen *info-'a');
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen break;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* unknown flag - ignore */
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk break;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
2e2a1d720ed53490e8e5c5031e773d395bd5683dTimo Sirainen }
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return flags;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char *maildir_filename_set_flags(const char *fname, enum mail_flags flags)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen string_t *flags_str;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *info, *oldflags;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int i, nextflag;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* remove the old :info from file name, and get the old flags */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen info = strrchr(fname, ':');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (info != NULL && strrchr(fname, '/') > info)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen info = NULL;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen oldflags = "";
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (info != NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen fname = t_strdup_until(fname, info);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (info[1] == '2' && info[2] == ',')
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen oldflags = info+3;
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen }
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen /* insert the new flags between old flags. flags must be sorted by
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen their ASCII code. unknown flags are kept. */
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen flags_str = t_str_new(256);
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen str_append(flags_str, fname);
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen str_append(flags_str, ":2,");
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen for (;;) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* skip all known flags */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen while (*oldflags == 'D' || *oldflags == 'F' ||
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen *oldflags == 'R' || *oldflags == 'S' ||
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen *oldflags == 'T' ||
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (*oldflags >= 'a' && *oldflags <= 'z'))
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen oldflags++;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen nextflag = *oldflags == '\0' || *oldflags == ',' ? 256 :
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (unsigned char) *oldflags;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((flags & MAIL_DRAFT) && nextflag > 'D') {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(flags_str, 'D');
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen flags &= ~MAIL_DRAFT;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((flags & MAIL_FLAGGED) && nextflag > 'F') {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(flags_str, 'F');
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen flags &= ~MAIL_FLAGGED;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen }
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen if ((flags & MAIL_ANSWERED) && nextflag > 'R') {
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen str_append_c(flags_str, 'R');
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen flags &= ~MAIL_ANSWERED;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((flags & MAIL_SEEN) && nextflag > 'S') {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(flags_str, 'S');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen flags &= ~MAIL_SEEN;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((flags & MAIL_DELETED) && nextflag > 'T') {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(flags_str, 'T');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen flags &= ~MAIL_DELETED;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if ((flags & MAIL_CUSTOM_FLAGS_MASK) && nextflag > 'a') {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (flags & (1 << (i + MAIL_CUSTOM_FLAG_1_BIT)))
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(flags_str, 'a' + i);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen flags &= ~MAIL_CUSTOM_FLAGS_MASK;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (*oldflags == '\0' || *oldflags == ',')
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen break;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(flags_str, *oldflags);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen oldflags++;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (*oldflags == ',') {
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen /* another flagset, we don't know about these, just keep them */
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen while (*oldflags != '\0')
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(flags_str, *oldflags++);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return str_c(flags_str);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainenstruct mail_index *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmaildir_index_alloc(const char *maildir, const char *index_dir,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *control_dir)
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen{
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen struct mail_index *index;
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen i_assert(maildir != NULL);
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen index = i_new(struct mail_index, 1);
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen memcpy(index, &maildir_index, sizeof(struct mail_index));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen index->maildir_lock_fd = -1;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen index->mailbox_path = i_strdup(maildir);
e911b23f3e05308df9b98b1a3fdaf72e4302d8fdTimo Sirainen index->control_dir = i_strdup(control_dir);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_init(index, index_dir);
77f1da4b5e2b800197d8db548235497d5e9d6a4fTimo Sirainen return index;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void maildir_index_free(struct mail_index *index)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (index->new_filenames != NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen hash_destroy(index->new_filenames);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (index->new_filename_pool != NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen pool_unref(index->new_filename_pool);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_close(index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_free(index->dir);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_free(index->mailbox_path);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_free(index->control_dir);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_free(index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic time_t maildir_get_internal_date(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct stat st;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *fname;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen time_t date;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* try getting it from cache */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen date = mail_get_internal_date(index, rec);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (date != (time_t)-1)
18f1bbf05980d3c53ecae81b62574212f0891522Timo Sirainen return date;
77f1da4b5e2b800197d8db548235497d5e9d6a4fTimo Sirainen
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen /* stat() gives it */
77f1da4b5e2b800197d8db548235497d5e9d6a4fTimo Sirainen fname = maildir_get_location(index, rec);
18f1bbf05980d3c53ecae81b62574212f0891522Timo Sirainen if (fname == NULL)
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen return (time_t)-1;
75e46142d8fbac811df8f2ca58d9a2f48a75d65fTimo Sirainen
77f1da4b5e2b800197d8db548235497d5e9d6a4fTimo Sirainen if (stat(fname, &st) < 0) {
18f1bbf05980d3c53ecae81b62574212f0891522Timo Sirainen index_file_set_syscall_error(index, fname, "stat()");
18f1bbf05980d3c53ecae81b62574212f0891522Timo Sirainen return (time_t)-1;
18f1bbf05980d3c53ecae81b62574212f0891522Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return st.st_mtime;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e911b23f3e05308df9b98b1a3fdaf72e4302d8fdTimo Sirainenstruct mail_index maildir_index = {
e911b23f3e05308df9b98b1a3fdaf72e4302d8fdTimo Sirainen maildir_index_open,
e911b23f3e05308df9b98b1a3fdaf72e4302d8fdTimo Sirainen maildir_index_free,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_set_lock,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_try_lock,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_set_lock_notify_callback,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen maildir_index_rebuild,
e911b23f3e05308df9b98b1a3fdaf72e4302d8fdTimo Sirainen mail_index_fsck,
e911b23f3e05308df9b98b1a3fdaf72e4302d8fdTimo Sirainen maildir_index_sync,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_get_header,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_lookup,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_next,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_lookup_uid_range,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_lookup_field,
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen mail_index_lookup_field_raw,
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen mail_index_cache_fields_later,
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen maildir_open_mail,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen maildir_get_internal_date,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_expunge,
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen maildir_index_update_flags,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_append_begin,
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen mail_index_append_end,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_append_abort,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_update_begin,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_update_end,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_update_abort,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen mail_index_update_field,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_update_field_raw,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_get_last_error,
04b7dc631f33bf61f273138c679da9bd0910fb6dTimo Sirainen mail_index_get_last_error_text,
04b7dc631f33bf61f273138c679da9bd0910fb6dTimo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen MAIL_INDEX_PRIVATE_FILL
04b7dc631f33bf61f273138c679da9bd0910fb6dTimo Sirainen};
04b7dc631f33bf61f273138c679da9bd0910fb6dTimo Sirainen