mail-transaction-log-view.c revision 7888a9d2008eab9985096c46e1da9ee985c22a2a
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen struct mail_transaction_expunge_traverse_ctx *exp_ctx;
aa797403d51ff047727b77d64532001d6b6cc21aTimo Sirainenmail_transaction_log_view_open(struct mail_transaction_log *log)
8c2b4a45f17a5cb13bb01058ca37798cf48d91baTimo Sirainen view = i_new(struct mail_transaction_log_view, 1);
b44033e45e9f48f8a6e1ac5905234fec5de6d6ccAki Tuomi buffer_create_dynamic(default_pool, 512, (size_t)-1);
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainenvoid mail_transaction_log_view_close(struct mail_transaction_log_view *view)
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainenmail_transaction_log_view_set(struct mail_transaction_log_view *view,
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen uint32_t min_file_seq, uoff_t min_file_offset,
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen uint32_t max_file_seq, uoff_t max_file_offset,
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen /* FIXME: error handling for "not found" case is bad.. should the
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen caller after all check it and handle as it sees best..? */
c13fce16374a6fa8d127742c527498d38e777789Timo Sirainen struct mail_transaction_log_file *file, *first;
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen i_assert(min_file_offset >= sizeof(struct mail_transaction_log_header));
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen i_assert(max_file_offset >= sizeof(struct mail_transaction_log_header));
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen min_file_seq == view->log->tail->hdr.prev_file_seq &&
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen min_file_offset == view->log->tail->hdr.prev_file_offset) {
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen /* we can skip this */
cdc7ca129c3433d3e4b9d5e90f4c209e4546dfe9Timo Sirainen ret = mail_transaction_log_file_find(view->log,
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen "Lost transaction log file %s seq %u",
1b7cd57585d8c2f133dd612d2d5d9c775595659fTimo Sirainen /* empty view */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (seq = min_file_seq+1; seq <= max_file_seq; seq++) {
5f5713d6468dca1acf3d350dd8a33057331f78c5Timo Sirainen if (file == NULL || file->hdr.file_seq != seq)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen end_offset = file->hdr.file_seq == max_file_seq ?
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen i_assert(max_file_offset <= file->hdr.used_size);
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen /* we have it all, refcount the files */
d3bae1f9d2448e5c398145ea250849ec12583845Timo Sirainen for (file = first, seq = min_file_seq; seq <= max_file_seq; seq++) {
58b8a301b7b36047f10a592751094fbed86d6f0cTimo Sirainenvoid mail_transaction_log_view_unset(struct mail_transaction_log_view *view)
3dc72a40e457658caa3c033fb6b3418d16e9fd21Timo Sirainen for (file = view->log->tail; file != NULL; file = file->next) {
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenmail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenmail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *fmt, ...)
e2fdcdb4ee53ab769123e27997713aaea34910e1Timo Sirainen mail_transaction_log_file_set_corrupted(view->log->head, "%s",
468c28dfb03613ab8d487b5aebc985a969193aceTimo Sirainenmail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view)
027f58ea63a1822bbf13d99ee5572e5f8b9e8d8bTimo Sirainenstatic int log_view_get_next(struct mail_transaction_log_view *view,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const void **data_r)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen const struct mail_transaction_type_map *type_rec;
f5d82a4b87a9b17894e1869cfe8b1a90afbced59Timo Sirainen view->file_offset = sizeof(struct mail_transaction_log_header);
550d2fe097e95f12e8fa60ef52753ea7fe53d4eaTimo Sirainen data = buffer_get_data(file->buffer, &file_size);
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainen if (view->file_offset + sizeof(*hdr) > file_size) {
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainen "offset points outside file "
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainen "(%"PRIuUOFF_T" + %"PRIuSIZE_T" > %"PRIuSIZE_T")",
36e091dc733c6cd690c5aae6e411e41adb1eca73Timo Sirainen hdr = CONST_PTR_OFFSET(data, view->file_offset - file->buffer_offset);
15ab2452b0220a115f4351ad9d7fd5ec70ae7966Timo Sirainen if (file_size - view->file_offset < hdr->size) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen "record size too large (type=0x%x, offset=%"PRIuUOFF_T
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen type_rec = mail_transaction_type_lookup(hdr->type);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "unknown record type 0x%x",
de92873c366becfaea1554642f89b9169d7955e2Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0) {
de92873c366becfaea1554642f89b9169d7955e2Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) !=
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen (MAIL_TRANSACTION_EXPUNGE|MAIL_TRANSACTION_EXPUNGE_PROT)) {
c3a2a487e23a282e59254b82deb9344ed0306bb2Timo Sirainen "found expunge without protection mask");
1f7f4294207557edf83171642ef62ce4922ffc9dTimo Sirainen } else if ((hdr->type & MAIL_TRANSACTION_TYPE_MASK) != type_rec->type) {
1f7f4294207557edf83171642ef62ce4922ffc9dTimo Sirainen "extra bits in header type: 0x%x",
void *context)
e->seq2);
if (expunges_before == 0) {
new_e = *e;
void *context)
u->seq2);
if (expunges_before == 0) {
new_u = *u;
void *context)
u->seq);
if (expunges_before != 0) {
new_u = *u;
u = &new_u;
const void *data;
int ret = 0;
if (ret <= 0)
return ret;
if (ret > 0) {
buffer_t *