mail-transaction-log-view.c revision d6f50f100ce17fa4b3a89e9567a5ff993b38b872
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail_transaction_log_file *cur, *head, *tail;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenmail_transaction_log_view_open(struct mail_transaction_log *log)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen view = i_new(struct mail_transaction_log_view, 1);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainenvoid mail_transaction_log_view_close(struct mail_transaction_log_view *view)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen for (p = &view->log->views; *p != NULL; p = &(*p)->next) {
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen for (file = view->tail; file != view->head; file = file->next)
cd8507179823de33d6e8242e10dbc15d136245b5Timo Sirainenvoid mail_transaction_log_views_close(struct mail_transaction_log *log)
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen for (view = log->views; view != NULL; view = view->next)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenmail_transaction_log_view_set(struct mail_transaction_log_view *view,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uint32_t min_file_seq, uoff_t min_file_offset,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uint32_t max_file_seq, uoff_t max_file_offset,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* FIXME: error handling for "not found" case is bad.. should the
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen caller after all check it and handle as it sees best..? */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_transaction_log_file *file, *first;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (min_file_seq == view->log->tail->hdr.prev_file_seq &&
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen min_file_offset == view->log->tail->hdr.prev_file_offset) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* we can skip this */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen min_file_offset = sizeof(struct mail_transaction_log_header);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* empty view */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "Lost transaction log file %s seq %u",
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen /* check these later than others as index file may have corrupted
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen log_file_offset. we should have recreated the log file and
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen skipped min_file_seq file above.. max_file_offset can be broken
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen only if min_file_seq = max_file_seq. */
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen "Lost transaction log file %s seq %u",
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen for (seq = min_file_seq+1; seq <= max_file_seq; seq++) {
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen if (file == NULL || file->hdr.file_seq != seq) {
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen "Lost transaction log file %s seq %u",
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen end_offset = file->hdr.file_seq == max_file_seq ?
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen "Lost transaction log file %s seq %u",
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen i_assert(max_file_offset <= file->hdr.used_size);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* we have all of them. update refcounts. */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (view->tail->hdr.file_seq < first->hdr.file_seq) {
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen /* unref old files */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (file = view->tail; file != first; file = file->next)
4145cbac82bfc0c8bfeceeca0ef841700117930cTimo Sirainen /* going backwards, reference them */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (file = first; file != view->tail; file = file->next)
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainen /* reference all new files */
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen for (file = view->head->next; file != NULL; file = file->next)
6b399f555c9c5c722d4cd5eab8faa02b2a4731d3Timo Sirainenmail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenmail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *fmt, ...)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_transaction_log_file_set_corrupted(view->log->head, "%s",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenmail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view)
d22301419109ed4a38351715e6760011421dadecTimo Sirainenstatic int log_view_get_next(struct mail_transaction_log_view *view,
d22301419109ed4a38351715e6760011421dadecTimo Sirainen const void **data_r)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen const struct mail_transaction_type_map *type_rec;
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen view->cur_offset = sizeof(struct mail_transaction_log_header);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen data = buffer_get_data(file->buffer, &file_size);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if (view->cur_offset + sizeof(*hdr) > file_size) {
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen "offset points outside file "
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen "(%"PRIuUOFF_T" + %"PRIuSIZE_T" > %"PRIuSIZE_T")",
c4bb0320ab43ea35fa6df88fc745fdad906cee44Timo Sirainen hdr = CONST_PTR_OFFSET(data, view->cur_offset - file->buffer_offset);
c4bb0320ab43ea35fa6df88fc745fdad906cee44Timo Sirainen if (file_size - view->cur_offset < hdr->size) {
047e3bbb00e68a0d43355e11a67b2e912e06de19Timo Sirainen "record size too large (type=0x%x, offset=%"PRIuUOFF_T
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen type_rec = mail_transaction_type_lookup(hdr->type);
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen "unknown record type 0x%x",
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) !=
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen (MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT)) {
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen "found expunge without protection mask");
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) != type_rec->type) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen "extra bits in header type: 0x%x",
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen } else if (hdr->type == MAIL_TRANSACTION_EXTRA_REC_UPDATE) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_transaction_extra_rec_header *ehdr = data;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (ehdr->idx >= view->log->index->extra_records_count) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen "extra record update out of range (%u > %u)",
eca30f1fe8556c46abc75c94d03f59b2e89d4162Timo Sirainen "record size wrong (type 0x%x, %u %% %u != 0)",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenint mail_transaction_log_view_next(struct mail_transaction_log_view *view,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen while ((ret = log_view_get_next(view, &hdr, &data)) > 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* we don't want this record */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* FIXME: hide flag/cache updates for appends if
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen append isn't in mask */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* hide expunge protection */