mail-transaction-log-view.c revision 1b56f5fdd415270c743a38719d41b4d9497bcacd
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_transaction_log_file *cur, *head, *tail;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenmail_transaction_log_view_open(struct mail_transaction_log *log)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view = i_new(struct mail_transaction_log_view, 1);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid mail_transaction_log_view_close(struct mail_transaction_log_view *view)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (p = &view->log->views; *p != NULL; p = &(*p)->next) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (file = view->tail; file != view->head; file = file->next)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenvoid mail_transaction_log_views_close(struct mail_transaction_log *log)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (view = log->views; view != NULL; view = view->next)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenmail_transaction_log_view_set(struct mail_transaction_log_view *view,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t min_file_seq, uoff_t min_file_offset,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen uint32_t max_file_seq, uoff_t max_file_offset,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* FIXME: error handling for "not found" case is bad.. should the
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen caller after all check it and handle as it sees best..? */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen struct mail_transaction_log_file *file, *first;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (min_file_seq == view->log->tail->hdr.prev_file_seq &&
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen min_file_offset == view->log->tail->hdr.prev_file_offset) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* we can skip this */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen min_file_offset = sizeof(struct mail_transaction_log_header);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* empty view */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "Lost transaction log file %s seq %u",
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen /* check these later than others as index file may have corrupted
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen log_file_offset. we should have recreated the log file and
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen skipped min_file_seq file above.. max_file_offset can be broken
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen only if min_file_seq = max_file_seq. */
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen "Lost transaction log file %s seq %u",
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen for (seq = min_file_seq+1; seq <= max_file_seq; seq++) {
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (file == NULL || file->hdr.file_seq != seq) {
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen "Lost transaction log file %s seq %u",
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen end_offset = file->hdr.file_seq == max_file_seq ?
f153a2cec0319f549388d28f8cfd4d50229d1132Timo Sirainen "Lost transaction log file %s seq %u",
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen i_assert(max_file_offset <= file->hdr.used_size);
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen /* we have all of them. update refcounts. */
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen if (view->tail->hdr.file_seq < first->hdr.file_seq) {
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen /* unref old files */
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen for (file = view->tail; file != first; file = file->next)
85144b5f0bc763de14c7d87291a90ef74ac241a2Timo Sirainen /* going backwards, reference them */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (file = first; file != view->tail; file = file->next)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* reference all new files */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen for (file = view->head->next; file != NULL; file = file->next)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenmail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainenmail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen const char *fmt, ...)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_transaction_log_file_set_corrupted(view->log->head, "%s",
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainenmail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view)
e64d7b6f388fecd0c83a4f2acb54e30d5ac98c6cTimo Sirainenstatic int log_view_get_next(struct mail_transaction_log_view *view,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const void **data_r)
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const struct mail_transaction_type_map *type_rec;
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen view->cur_offset = sizeof(struct mail_transaction_log_header);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen data = buffer_get_data(file->buffer, &file_size);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (view->cur_offset + sizeof(*hdr) > file_size) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "offset points outside file "
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "(%"PRIuUOFF_T" + %"PRIuSIZE_T" > %"PRIuSIZE_T")",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen hdr = CONST_PTR_OFFSET(data, view->cur_offset - file->buffer_offset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if (file_size - view->cur_offset < hdr->size) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "record size too large (type=0x%x, offset=%"PRIuUOFF_T
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen type_rec = mail_transaction_type_lookup(hdr->type);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "unknown record type 0x%x",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) !=
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen (MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT)) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "found expunge without protection mask");
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen } else if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) != type_rec->type) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "extra bits in header type: 0x%x",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen "record size wrong (type 0x%x, %u %% %u != 0)",
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen *data_r = CONST_PTR_OFFSET(data, view->cur_offset -
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint mail_transaction_log_view_next(struct mail_transaction_log_view *view,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen while ((ret = log_view_get_next(view, &hdr, &data)) > 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* we don't want this record */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* FIXME: hide flag/cache updates for appends if
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen append isn't in mask */
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen /* hide expunge protection */