mail-transaction-log-view.c revision 1f2c3bde353d45f6d76c5210adf1e0a952247f3a
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose/* Copyright (C) 2003-2004 Timo Sirainen */
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose#include "lib.h"
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose#include "buffer.h"
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose#include "mail-index-private.h"
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose#include "mail-transaction-log-private.h"
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose#include "mail-transaction-util.h"
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bosestruct mail_transaction_log_view {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_log *log;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_log_view *next;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uint32_t min_file_seq, max_file_seq;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uoff_t min_file_offset, max_file_offset;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose enum mail_transaction_type type_mask;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose buffer_t *expunges_buf, *data_buf;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_expunge_iter_ctx *exp_ctx;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_header tmp_hdr;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_log_file *file;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uoff_t file_offset;
6cb34580ee6e9e2c9190b77b10db8a3c43e3c9c8Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uint32_t prev_file_seq;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio uoff_t prev_file_offset;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio unsigned int broken:1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose};
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bosestruct mail_transaction_log_view *
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bosemail_transaction_log_view_open(struct mail_transaction_log *log)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose{
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_log_view *view;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view = i_new(struct mail_transaction_log_view, 1);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->log = log;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->broken = TRUE;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->expunges_buf =
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose buffer_create_dynamic(default_pool, 512, (size_t)-1);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->next = log->views;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose log->views = view;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose return view;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose}
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bosevoid mail_transaction_log_view_close(struct mail_transaction_log_view *view)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose{
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_log_view **p;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose for (p = &view->log->views; *p != NULL; p = &(*p)->next) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (*p == view) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose *p = view->next;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose break;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose mail_transaction_log_view_unset(view);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (view->data_buf != NULL)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose buffer_free(view->data_buf);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose buffer_free(view->expunges_buf);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose i_free(view);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose}
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bosevoid mail_transaction_log_views_close(struct mail_transaction_log *log)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose{
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_log_view *view;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose for (view = log->views; view != NULL; view = view->next)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->log = NULL;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose}
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Boseint
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bosemail_transaction_log_view_set(struct mail_transaction_log_view *view,
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uint32_t min_file_seq, uoff_t min_file_offset,
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uint32_t max_file_seq, uoff_t max_file_offset,
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose enum mail_transaction_type type_mask)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose{
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose /* FIXME: error handling for "not found" case is bad.. should the
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose caller after all check it and handle as it sees best..? */
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose struct mail_transaction_log_file *file, *first;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uint32_t seq;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose uoff_t end_offset;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose int ret;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose i_assert(view->broken);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose i_assert(min_file_seq <= max_file_seq);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (view->log == NULL)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose return -1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (ret <= 0) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (ret == 0 &&
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose min_file_seq == view->log->tail->hdr.prev_file_seq &&
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose min_file_offset == view->log->tail->hdr.prev_file_offset) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose /* we can skip this */
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose min_file_seq = view->log->tail->hdr.file_seq;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose min_file_offset =
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose sizeof(struct mail_transaction_log_header);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose ret = mail_transaction_log_file_find(view->log,
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose min_file_seq,
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose &file);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (ret == 0) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose mail_index_set_error(view->log->index,
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose "Lost transaction log file %s seq %u",
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->log->tail->filepath, min_file_seq);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (ret <= 0)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose return -1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (min_file_seq > max_file_seq) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose /* empty view */
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose max_file_seq = min_file_seq;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose max_file_offset = min_file_offset;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose /* check these later than others as index file may have corrupted
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose log_file_offset. we should have recreated the log file and
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose skipped min_file_seq file above.. max_file_offset can be broken
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose only if min_file_seq = max_file_seq. */
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose end_offset = min_file_seq == max_file_seq ?
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose max_file_offset : (uoff_t)-1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
cd5033e86bb4065d75188e2b6ef287a4421344c8Sumit Bose if (ret <= 0)
cd5033e86bb4065d75188e2b6ef287a4421344c8Sumit Bose return -1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose first = file;
cd5033e86bb4065d75188e2b6ef287a4421344c8Sumit Bose
cd5033e86bb4065d75188e2b6ef287a4421344c8Sumit Bose for (seq = min_file_seq+1; seq <= max_file_seq; seq++) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose file = file->next;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (file == NULL || file->hdr.file_seq != seq)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose return -1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose end_offset = file->hdr.file_seq == max_file_seq ?
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose max_file_offset : (uoff_t)-1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose ret = mail_transaction_log_file_map(file,
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose sizeof(struct mail_transaction_log_header),
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose end_offset);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (ret <= 0)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose return -1;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose i_assert(max_file_offset <= file->hdr.used_size);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose /* we have it all, refcount the files */
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose for (file = first, seq = min_file_seq; seq <= max_file_seq; seq++) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose file->refcount++;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose file = file->next;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose }
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose buffer_set_used_size(view->expunges_buf, 0);
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->prev_file_seq = 0;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->prev_file_offset = 0;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->file = first;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->file_offset = min_file_offset;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->min_file_seq = min_file_seq;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->min_file_offset = min_file_offset;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->max_file_seq = max_file_seq;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->max_file_offset = max_file_offset;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->type_mask = type_mask;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->broken = FALSE;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose return 0;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose}
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnikvoid mail_transaction_log_view_unset(struct mail_transaction_log_view *view)
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik{
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik struct mail_transaction_log_file *file;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (view->broken)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose return;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose view->broken = TRUE;
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose for (file = view->log->tail; file != NULL; file = file->next) {
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose if (file->hdr.file_seq > view->max_file_seq)
2ef62c64e7f07c8aced3f72850008ecb72860162Sumit Bose break;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose if (file->hdr.file_seq >= view->min_file_seq)
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio file->refcount--;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio }
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio mail_transaction_logs_clean(view->log);
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio}
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidênciovoid
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidênciomail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio uint32_t *file_seq_r,
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio uoff_t *file_offset_r)
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio{
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio *file_seq_r = view->prev_file_seq;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio *file_offset_r = view->prev_file_offset;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio}
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidênciovoid
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidênciomail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio const char *fmt, ...)
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio{
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio va_list va;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio if (!view->broken)
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio mail_transaction_log_view_unset(view);
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio view->broken = TRUE;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio va_start(va, fmt);
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio t_push();
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio mail_transaction_log_file_set_corrupted(view->log->head, "%s",
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio t_strdup_vprintf(fmt, va));
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio t_pop();
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio va_end(va);
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio}
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncioint
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidênciomail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view)
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio{
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio return view->broken;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio}
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidênciostatic int log_view_get_next(struct mail_transaction_log_view *view,
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio const struct mail_transaction_header **hdr_r,
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio const void **data_r)
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio{
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio const struct mail_transaction_header *hdr;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio struct mail_transaction_log_file *file;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio const struct mail_transaction_type_map *type_rec;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio const void *data;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio unsigned int record_size;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio size_t file_size;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio for (;;) {
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio file = view->file;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio view->prev_file_seq = file->hdr.file_seq;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio view->prev_file_offset = view->file_offset;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio if (view->file_offset != file->hdr.used_size)
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio break;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio view->file = file->next;
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio view->file_offset = sizeof(struct mail_transaction_log_header);
fb81f337b68c85471c3f5140850dccf549a2d0acFabiano Fidêncio
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose if (view->file == NULL)
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose return 0;
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose }
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose data = buffer_get_data(file->buffer, &file_size);
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose file_size += file->buffer_offset;
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose if (view->file_offset + sizeof(*hdr) > file_size) {
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose mail_transaction_log_file_set_corrupted(file,
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose "offset points outside file "
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose "(%"PRIuUOFF_T" + %"PRIuSIZE_T" > %"PRIuSIZE_T")",
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose view->file_offset, sizeof(*hdr), file_size);
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose return -1;
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose }
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose hdr = CONST_PTR_OFFSET(data, view->file_offset - file->buffer_offset);
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose view->file_offset += sizeof(*hdr);
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose if (file_size - view->file_offset < hdr->size) {
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose mail_transaction_log_file_set_corrupted(file,
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose "record size too large (type=0x%x, offset=%"PRIuUOFF_T
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose ", size=%u, end=%"PRIuSIZE_T")",
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose hdr->type & MAIL_TRANSACTION_TYPE_MASK,
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose view->file_offset, hdr->size, file_size);
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose view->file_offset = file_size;
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose return -1;
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose }
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose type_rec = mail_transaction_type_lookup(hdr->type);
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose if (type_rec != NULL)
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose record_size = type_rec->record_size;
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose else {
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose mail_transaction_log_file_set_corrupted(file,
fe2ab0d67fe8c66fb6352e9d8f845bb46d1848cbSumit Bose "unknown record type 0x%x",
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose hdr->type & MAIL_TRANSACTION_TYPE_MASK);
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose view->file_offset = file->hdr.used_size;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return -1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) !=
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose (MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT)) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose mail_transaction_log_file_set_corrupted(file,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose "found expunge without protection mask");
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return -1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose } else if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) != type_rec->type) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose mail_transaction_log_file_set_corrupted(file,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose "extra bits in header type: 0x%x",
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose hdr->type & MAIL_TRANSACTION_TYPE_MASK);
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return -1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (hdr->size % record_size != 0) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose mail_transaction_log_file_set_corrupted(file,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose "record size wrong (type 0x%x, %u %% %u != 0)",
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose hdr->type & MAIL_TRANSACTION_TYPE_MASK,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose hdr->size, record_size);
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose view->file_offset = file->hdr.used_size;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return -1;
87f8bee53ee1b4ca87b602ff8536bc5fd5b5b595Lukas Slebodnik }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose *hdr_r = hdr;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose *data_r = CONST_PTR_OFFSET(data, view->file_offset -
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose file->buffer_offset);
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose view->file_offset += hdr->size;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return 1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose}
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bosestatic int seqfix_expunge(const struct mail_transaction_expunge *e,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose void *context)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose{
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose struct mail_transaction_log_view *view = context;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose struct mail_transaction_expunge new_e;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (!mail_transaction_expunge_iter_seek(view->exp_ctx,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose e->seq1, e->seq2)) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose new_e = *e;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose /*FIXME:buffer_append(view->data_buf, e, sizeof(*e));
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return 1;*/
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose new_e.uid1 = new_e.uid2 = 0; // FIXME: this breaks anyway
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose while (mail_transaction_expunge_iter_get(view->exp_ctx,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose &new_e.seq1, &new_e.seq2)) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose i_assert(new_e.seq1 != 0);
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose buffer_append(view->data_buf, &new_e, sizeof(new_e));
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return 1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose}
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bosestatic int seqfix_flag_update(const struct mail_transaction_flag_update *u,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose void *context)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose{
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose struct mail_transaction_log_view *view = context;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose struct mail_transaction_flag_update new_u;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (!mail_transaction_expunge_iter_seek(view->exp_ctx,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose u->seq1, u->seq2)) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose buffer_append(view->data_buf, u, sizeof(*u));
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return 1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose new_u = *u;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose while (mail_transaction_expunge_iter_get(view->exp_ctx,
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik &new_u.seq1, &new_u.seq2))
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik buffer_append(view->data_buf, &new_u, sizeof(new_u));
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik return 1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose}
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bosestatic int seqfix_cache_update(const struct mail_transaction_cache_update *u,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose void *context)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose{
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose struct mail_transaction_log_view *view = context;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose struct mail_transaction_cache_update new_u;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (!mail_transaction_expunge_iter_seek(view->exp_ctx,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose u->seq, u->seq)) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose buffer_append(view->data_buf, u, sizeof(*u));
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return 1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose new_u = *u;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (mail_transaction_expunge_iter_get(view->exp_ctx,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose &new_u.seq, &new_u.seq))
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose buffer_append(view->data_buf, &new_u, sizeof(new_u));
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return 1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose}
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnikint mail_transaction_log_view_next(struct mail_transaction_log_view *view,
04d138472cc086fb7961f0d378852b09961b1a33Lukas Slebodnik const struct mail_transaction_header **hdr_r,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose const void **data_r, int *skipped_r)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose{
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose struct mail_transaction_map_functions seqfix_funcs = {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose seqfix_expunge, NULL, seqfix_flag_update, seqfix_cache_update
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose };
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose const struct mail_transaction_header *hdr;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose const void *data;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose int ret = 0;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (skipped_r != NULL)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose *skipped_r = FALSE;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (view->broken)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose return -1;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose while ((ret = log_view_get_next(view, &hdr, &data)) > 0) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if ((view->type_mask & hdr->type) != 0)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose break;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose /* we don't want this record */
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if (skipped_r != NULL)
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose *skipped_r = TRUE;
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose mail_transaction_log_sort_expunges(view->expunges_buf,
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose data, hdr->size);
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose /* FIXME: hide flag/cache updates for appends if
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose append isn't in mask */
2fe140d3a41e1ac66400069d35adc9379348c1e5Sumit Bose }
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose if (ret <= 0)
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose return ret;
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose *hdr_r = hdr;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose *data_r = data;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose if (buffer_get_used_size(view->expunges_buf) > 0) {
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose /* we have to fix sequences in the data */
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose if (view->data_buf == NULL) {
da1fd52202cffa3260470565b74af885a466cb00Jakub Hrozek view->data_buf =
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose buffer_create_dynamic(default_pool,
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose hdr->size, (size_t)-1);
da1fd52202cffa3260470565b74af885a466cb00Jakub Hrozek } else {
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose buffer_set_used_size(view->data_buf, 0);
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose }
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose view->exp_ctx =
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose mail_transaction_expunge_iter_init(view->expunges_buf);
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose ret = mail_transaction_map(hdr, data, &seqfix_funcs, view);
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose mail_transaction_expunge_iter_deinit(view->exp_ctx);
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose if (ret > 0) {
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose /* modified - size may have changed, so update header */
da1fd52202cffa3260470565b74af885a466cb00Jakub Hrozek view->tmp_hdr = *hdr;
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose view->tmp_hdr.size =
9da27cbc7532f775afc411d809735760dd5294a7Sumit Bose buffer_get_used_size(view->data_buf);
da1fd52202cffa3260470565b74af885a466cb00Jakub Hrozek *hdr_r = &view->tmp_hdr;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose *data_r = buffer_get_data(view->data_buf, NULL);
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose } else {
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose i_assert(buffer_get_used_size(view->data_buf) == 0);
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose }
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose }
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose mail_transaction_log_sort_expunges(view->expunges_buf,
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose data, hdr->size);
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose /* hide expunge protection */
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose if (*hdr_r != &view->tmp_hdr) {
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose view->tmp_hdr = *hdr;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose *hdr_r = &view->tmp_hdr;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose }
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose view->tmp_hdr.type &= ~MAIL_TRANSACTION_EXPUNGE_PROT;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose }
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose return 1;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose}
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bosebuffer_t *
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bosemail_transaction_log_view_get_expunges(struct mail_transaction_log_view *view)
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose{
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose return view->expunges_buf;
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose}
ca49ae1eee321751681e99f3ebe2547211db3bf6Sumit Bose