mbox-sync.c revision 064bfeee2f9156683b191cc0f3f7b242720942f7
7088N/A/* Copyright (C) 2004 Timo Sirainen */ 7088N/A Modifying mbox can be slow, so we try to do it all at once minimizing the 7088N/A required disk I/O. We may need to: 7088N/A - Update message flags in Status, X-Status and X-Keywords headers 7088N/A - Write missing X-UID and X-IMAPbase headers 7088N/A - Write missing or broken Content-Length header if there's space 7088N/A - Expunge specified messages 7088N/A - Start reading the mails from the beginning 7088N/A - X-Keywords, X-UID and X-IMAPbase headers may contain padding at the end 7088N/A of them, remember how much each message has and offset to beginning of the 7088N/A - If header needs to be rewritten and there's enough space, do it 7088N/A - If we didn't have enough space, remember how much was missing 7088N/A - Continue reading and counting the padding in each message. If available 7088N/A padding is enough to rewrite all the previous messages needing it, do it 7088N/A - When we encounter expunged message, treat all of it as padding and 7088N/A rewrite previous messages if needed (and there's enough space). 7088N/A Afterwards keep moving messages backwards to fill the expunged space. 7088N/A Moving is done by rewriting each message's headers, with possibly adding 7088N/A missing Content-Length header and padding. Message bodies are moved 7088N/A - If we encounter end of file, grow the file and rewrite needed messages 7088N/A - Rewriting is done by moving message body forward, rewriting message's 7088N/A header and doing the same for previous message, until all of them are 7088N/A /* put the padding between last message's header and body */ 7088N/A /* First message was expunged and this is the next one. 7088N/A /* need to add 'O' flag to Status-header */ 7088N/A /* nothing for this or the future ones */ 7088N/A /* externally expunged message, remove from index */ 7088N/A /* this UID was already in index and it was expunged */ 7088N/A "mbox sync: Expunged message reappeared in mailbox %s " /* new UID in the middle of the mailbox - shouldn't happen */ "mbox sync: UID inserted in the middle of mailbox %s " /* externally expunged message, remove from index */ /* see if from_offset needs updating */ /*FIXME:mail_cache_add(sync_ctx->cache_trans, str_data(mail_ctx->uidl), str_len(mail_ctx->uidl));*/ /* see if flags changed */ /* update from_offsets, but not if we're going to rewrite this message. rewriting would just move it anyway. */ const unsigned char *
data;
/* pseudo-header, skip it */ /* expunging first message, fix space to contain next message's \n header too since it will be removed. */ /* move the header backwards to fill expunged space */ /* read the From-line before rewriting overwrites it */ /* rewrite successful, write From-line to /* first mail with no space to write it */ /* create dummy message to describe the expunged data */ /* we have enough space now */ /* don't waste too much on padding */ /* mail_ctx may contain wrong data after rewrite, so make sure we don't try to access it */ "Mailbox isn't a valid mbox file");
"Error seeking back to original " "offset %s in mbox file %s",
/* set to -1, since it's always increased later */ /* this mbox has pseudo mail which contains the X-IMAP header */ /* we sync only what we need to. jump to first record that /* get all sync records related to this message */ /* Read-only mboxes use MD5 sums. */ /* if there's no sync records left, /* we can skip forward to next record which needs updating. if it failes because the offset is dirty, just ignore and continue from where we are now. */ /* rest of the messages in index don't exist -> expunge them */ /* copy trailer, then truncate the file */ /* we couldn't rewrite X-IMAPbase because it's /* file is fully synced */ /* we want to do full syncing */ /* see if we can delay syncing the whole file. normally we only notice expunges and appends /* partial syncing didn't work, do it again */ /* only syncs left should be just appends (and their updates) which weren't synced yet for some reason (crash). we'll just ignore them, as we've overwritten them above. */ /* we just want to lock it for reading. if mbox hasn't been modified don't do any syncing. */ /* have to sync to make sure offsets have stayed the same */ /* we're most likely modifying the mbox while syncing, just lock it for writing immediately. the mbox must be locked before index syncing is started to avoid deadlocks, so we don't have much choice either (well, easy ones anyway). */ /* ok, we have something to do but no locks. we'll have to restart syncing to avoid deadlocking. */ /* rewrite X-IMAPbase header. do it after mail_index_sync_end() so previous transactions have been committed. */ /* FIXME: keep the lock MBOX_SYNC_SECS+1 to make sure we notice changes made by others .. and this has to be done even if lock_reading is set.. except if mbox_sync_dirty = TRUE */