mail-transaction-log-view.c revision 8830fab191cab8440281eb641dfdd93974b2933b
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (C) 2003-2004 Timo Sirainen */
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen struct mail_transaction_log_file *cur, *head, *tail;
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainenmail_transaction_log_view_open(struct mail_transaction_log *log)
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen view = i_new(struct mail_transaction_log_view, 1);
379175cfba8150d481d9898b78330b719d128d84Timo Sirainenvoid mail_transaction_log_view_close(struct mail_transaction_log_view *view)
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen for (p = &view->log->views; *p != NULL; p = &(*p)->next) {
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen for (file = view->tail; file != view->head; file = file->next)
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainenvoid mail_transaction_log_views_close(struct mail_transaction_log *log)
a8d47e2427558d5011dfc75694b704760c1ef8baTimo Sirainen for (view = log->views; view != NULL; view = view->next)
379175cfba8150d481d9898b78330b719d128d84Timo Sirainenmail_transaction_log_view_set(struct mail_transaction_log_view *view,
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen uint32_t min_file_seq, uoff_t min_file_offset,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen uint32_t max_file_seq, uoff_t max_file_offset,
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen /* FIXME: error handling for "not found" case is bad.. should the
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen caller after all check it and handle as it sees best..? */
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen struct mail_transaction_log_file *file, *first;
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen if (min_file_seq == view->log->tail->hdr.prev_file_seq &&
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen min_file_offset == view->log->tail->hdr.prev_file_offset) {
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen /* we can skip this */
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen min_file_offset = sizeof(struct mail_transaction_log_header);
34512eaad8b1b2f929e6d6e3a2f7252c29fba97bTimo Sirainen /* empty view */
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen "Lost transaction log file %s seq %u",
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen /* check these later than others as index file may have corrupted
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen log_file_offset. we should have recreated the log file and
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen skipped min_file_seq file above.. max_file_offset can be broken
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen only if min_file_seq = max_file_seq. */
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen "Lost transaction log file %s seq %u",
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen for (seq = min_file_seq+1; seq <= max_file_seq; seq++) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (file == NULL || file->hdr.file_seq != seq) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen "Lost transaction log file %s seq %u",
39993536eaef0a23954105e41040dcf88afd2e7eTimo Sirainen end_offset = file->hdr.file_seq == max_file_seq ?
326c86b1cdb555957b236958e17142e82e34074eTimo Sirainen "Lost transaction log file %s seq %u",
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen i_assert(max_file_offset <= file->hdr.used_size);
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen /* we have all of them. update refcounts. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (view->tail->hdr.file_seq < first->hdr.file_seq) {
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen /* unref old files */
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen for (file = view->tail; file != first; file = file->next)
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen /* going backwards, reference them */
7b64db32b95286235612eebb5d37d296a49306f7Timo Sirainen for (file = first; file != view->tail; file = file->next)
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen /* reference all new files */
a26b7e87b4157cfa800f9bcd8c4c044462d21268Timo Sirainen for (file = view->head->next; file != NULL; file = file->next)
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainenmail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
4f2fa2e5f5a27e1d59dd38fbbf38e420e006596dTimo Sirainenmail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,
e51cfb5506de764499cb5b81a098b23cf46f90f1Timo Sirainen const char *fmt, ...)
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainen mail_transaction_log_file_set_corrupted(view->log->head, "%s",
a443e5aaf632257bfd1e7aa9b3c42c09512bbe43Timo Sirainenmail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic int log_view_get_next(struct mail_transaction_log_view *view,
013a8a91c83c6ea24bc75322b81235f19e26fa8fTimo Sirainen const void **data_r)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct mail_transaction_type_map *type_rec;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen view->cur_offset = sizeof(struct mail_transaction_log_header);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen data = buffer_get_data(file->buffer, &file_size);
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen if (view->cur_offset + sizeof(*hdr) > file_size) {
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen "offset points outside file "
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen "(%"PRIuUOFF_T" + %"PRIuSIZE_T" > %"PRIuSIZE_T")",
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen hdr = CONST_PTR_OFFSET(data, view->cur_offset - file->buffer_offset);
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen if (file_size - view->cur_offset < hdr->size) {
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen "record size too large (type=0x%x, offset=%"PRIuUOFF_T
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen type_rec = mail_transaction_type_lookup(hdr->type);
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen "unknown record type 0x%x",
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) !=
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen (MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT)) {
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen "found expunge without protection mask");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen } else if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) != type_rec->type) {
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen "extra bits in header type: 0x%x",
bcf1cf2afb9692b0db555e6ecf662a2fbd19793dTimo Sirainen "record size wrong (type 0x%x, %u %% %u != 0)",
d80f37f025593d959bdfa9c378915e4322f4f504Timo Sirainen *data_r = CONST_PTR_OFFSET(data, view->cur_offset -
4654f788834c9d7920a351306b89cf5d1c21772eTimo Sirainenint mail_transaction_log_view_next(struct mail_transaction_log_view *view,
94ce7e7700cda14a8342cb08e7285507b4b531daTimo Sirainen while ((ret = log_view_get_next(view, &hdr, &data)) > 0) {
311d3dd2078c1b711a0cef013ba43a94078c115cTimo Sirainen /* we don't want this record */
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen /* FIXME: hide flag/cache updates for appends if
3398d5e2b883812de5d569721c8294b581e1d9e6Timo Sirainen append isn't in mask */
b06633c63fde22b6c8837ae70b2f95fe60075b0aTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
b06633c63fde22b6c8837ae70b2f95fe60075b0aTimo Sirainen /* hide expunge protection */