mbox-sync.c revision dda2c506c8fc8ac2f88272de4523ded42baa0aa0
2875N/A/* Copyright (C) 2004 Timo Sirainen */ 2875N/A Modifying mbox can be slow, so we try to do it all at once minimizing the 2875N/A required disk I/O. We may need to: 2875N/A - Update message flags in Status, X-Status and X-Keywords headers 2875N/A - Write missing X-UID and X-IMAPbase headers 2875N/A - Write missing or broken Content-Length header if there's space 2875N/A - Expunge specified messages 2875N/A - Start reading the mails mail headers from the beginning 2875N/A - X-Keywords and X-UID headers may contain extra spaces at the end of them, 2875N/A remember how much extra each message has and offset to beginning of the 2875N/A - If message flags are dirty and there's enough space to write them, do it 2875N/A - If we didn't have enough space, remember how much was missing and keep 2875N/A - When we encounter expunged message, check if the amount of empty space in 2875N/A previous messages plus size of expunged message is enough to cover the 2875N/A - forget all the messages before the expunged message. only remember 2875N/A how much data we still have to move to cover the expunged message 2875N/A - If we encounter end of file, grow the file and execute the rewrite plan 2875N/A - Start from the first message that needs more space 2875N/A - If there's expunged messages before us, we have to write over them. 2875N/A - Move all messages after it backwards to fill it 2875N/A - Each moved message's X-Keywords header should have n bytes extra 2875N/A space, unless there's not enough space to do it. 2875N/A - If there's no expunged messages, we can move data either forward or 2875N/A backward to get it. Calculate which requires less moving. Forward 2875N/A counting may encounter more messages which require extra space, count 2875N/A - If we decide to move forwards and we had to go through dirty 2875N/A messages, do the moving from last to first dirty message 2875N/A - If we encounter end of file, grow the file enough to get the required 2875N/A amount of space plus enough space to fill X-Keywords headers full of 2875N/A /* put the extra space between last message's header and body */ 2875N/A /* First message was expunged and this is the next one. 2875N/A /* save the offset permanently with recent flag state */ 2875N/A /* need to add 'O' flag to Status-header */ 2875N/A // FIXME: save it somewhere 2875N/A /* externally expunged message, remove from index */ 2875N/A /* new UID in the middle of the mailbox - shouldn't happen */ 2875N/A "mbox sync: UID inserted in the middle of mailbox " 2875N/A /* see if from_offset needs updating */ 2875N/A /* update from_offsets, but not if we're going to rewrite this message. 2875N/A rewriting would just move it anyway. */ 2875N/A /* expunging first message, fix space to contain next 2875N/A message's \n header too since it will be removed. */ 2875N/A /* move the header backwards to fill expunged space */ 2875N/A /* read the From-line before rewriting overwrites it */ 2875N/A /* rewrite successful, write From-line to 2875N/A /* first mail with no space to write it */ 2875N/A /* create dummy message to describe the expunged data */ 2875N/A /* we have enough space now */ 2875N/A /* don't waste too much on extra spacing */ 2875N/A /* mail_ctx may contain wrong data after rewrite, so make sure we 2875N/A /* get all sync records related to this message */ 2875N/A /* -1 = error, -2 = need exclusive lock */ 2875N/A /* rest of the messages in index don't exist -> expunge them */ 2875N/A /* copy trailer, then truncate the file */ 2875N/A /* we want to modify mbox, get exclusive lock. this requires 2875N/A dropping the read lock first, so we have to parse the whole 2875N/A /* FIXME: if mbox timestamp hasn't changed and it's older than 2875N/A 2 secs, we could continue from where we left */ 2875N/A // FIXME: rewrite X-IMAPbase header 2875N/A /* only syncs left should be just appends (and their updates) 2875N/A which weren't synced yet for some reason (crash). we'll just 2875N/A ignore them, as we've overwritten them above. */