view src/lib-storage/index/dbox-single/sdbox-mail.c @ 12646:87f84a76fb1e

lib-storage: Return STATUS replies from mailbox list index only when it's fully up-to-date.
author Timo Sirainen <tss@iki.fi>
date Wed, 09 Feb 2011 01:31:40 +0200
parents 9e400f6963eb
children 447bce266022
line wrap: on
line source

/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "ioloop.h"
#include "istream.h"
#include "str.h"
#include "index-mail.h"
#include "dbox-mail.h"
#include "sdbox-storage.h"
#include "sdbox-file.h"

#include <stdlib.h>
#include <sys/stat.h>

static void sdbox_mail_set_expunged(struct dbox_mail *mail)
{
	struct mail *_mail = &mail->imail.mail.mail;

	/* syncing code first unlinks the file, and index is updated later.
	   so at this point we don't know if the file was unexpectedly lost
	   or if it's just being expunged. just assume the latter. */
	mail_set_expunged(_mail);
}

static bool sdbox_mail_file_set(struct dbox_mail *mail)
{
	struct mail *_mail = &mail->imail.mail.mail;
	struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)_mail->box;
	bool deleted;
	int ret;

	if (mail->open_file != NULL) {
		/* already set */
		return FALSE;
	} else if (!_mail->saving) {
		mail->open_file = sdbox_file_init(mbox, _mail->uid);
		return FALSE;
	} else {
		/* mail is being saved in this transaction */
		mail->open_file =
			sdbox_save_file_get_file(_mail->transaction,
						 _mail->seq);
		mail->open_file->refcount++;

		/* it doesn't have input stream yet */
		ret = dbox_file_open(mail->open_file, &deleted);
		i_assert(ret > 0);
		return TRUE;
	}
}

int sdbox_mail_open(struct dbox_mail *mail, uoff_t *offset_r,
		    struct dbox_file **file_r)
{
	struct mail *_mail = &mail->imail.mail.mail;
	bool deleted;

	if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) {
		mail_set_aborted(_mail);
		return -1;
	}

	if (!sdbox_mail_file_set(mail)) {
		if (!dbox_file_is_open(mail->open_file))
			mail->imail.mail.stats_open_lookup_count++;
		if (dbox_file_open(mail->open_file, &deleted) <= 0)
			return -1;
		if (deleted) {
			sdbox_mail_set_expunged(mail);
			return -1;
		}
	}

	*file_r = mail->open_file;
	*offset_r = 0;
	return 0;
}

struct mail_vfuncs sdbox_mail_vfuncs = {
	dbox_mail_close,
	index_mail_free,
	index_mail_set_seq,
	index_mail_set_uid,
	index_mail_set_uid_cache_updates,

	index_mail_get_flags,
	index_mail_get_keywords,
	index_mail_get_keyword_indexes,
	index_mail_get_modseq,
	index_mail_get_parts,
	index_mail_get_date,
	dbox_mail_get_received_date,
	dbox_mail_get_save_date,
	dbox_mail_get_virtual_size,
	dbox_mail_get_physical_size,
	index_mail_get_first_header,
	index_mail_get_headers,
	index_mail_get_header_stream,
	dbox_mail_get_stream,
	dbox_mail_get_special,
	index_mail_get_real_mail,
	index_mail_update_flags,
	index_mail_update_keywords,
	index_mail_update_modseq,
	NULL,
	index_mail_expunge,
	index_mail_set_cache_corrupted,
	index_mail_opened
};