mbox-sync.c revision 7a6b45405fb1544ac476e6eb1402a70cc1ddcdcf
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa/* Copyright (C) 2004 Timo Sirainen */
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa Modifying mbox can be slow, so we try to do it all at once minimizing the
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa required disk I/O. We may need to:
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - Update message flags in Status, X-Status and X-Keywords headers
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - Write missing X-UID and X-IMAPbase headers
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - Write missing or broken Content-Length header if there's space
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - Expunge specified messages
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa Here's how we do it:
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - Start reading the mails from the beginning
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - X-Keywords, X-UID and X-IMAPbase headers may contain padding at the end
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa of them, remember how much each message has and offset to beginning of the
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - If header needs to be rewritten and there's enough space, do it
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - If we didn't have enough space, remember how much was missing
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - Continue reading and counting the padding in each message. If available
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa padding is enough to rewrite all the previous messages needing it, do it
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa - When we encounter expunged message, treat all of it as padding and
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa rewrite previous messages if needed (and there's enough space).
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa Afterwards keep moving messages backwards to fill the expunged space.
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa Moving is done by rewriting each message's headers, with possibly adding
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa missing Content-Length header and padding. Message bodies are moved
6f74297c639ecd2696280eb0db456ffad65515deEugen Kuksa without modifications.
#include "lib.h"
#include "ioloop.h"
#include "buffer.h"
#include "istream.h"
#include "file-set-size.h"
#include "str.h"
#include "write-full.h"
#include "istream-raw-mbox.h"
#include "mbox-storage.h"
#include "mbox-file.h"
#include "mbox-lock.h"
#include "mbox-sync-private.h"
#include <stddef.h>
#include <stdlib.h>
dest++;
for (i = 0; i < size; i++) {
return TRUE;
return FALSE;
int ret;
if (uid == 0) {
sizeof(*sync_rec));
if (ret < 0) {
if (ret == 0) {
if (!*sync_expunge_r)
for (i = 0; i < size; i++) {
int ret = 0;
if (ret < 0) {
ret = 0;
return ret;
unsigned char hdr_md5_sum[],
const void *data;
int ret;
if (ret < 0) {
&data) < 0) {
int nocheck)
const void *data;
if (!nocheck) {
&data) < 0) {
INDEX_KEYWORDS_BYTE_COUNT) == 0) {
MAIL_INDEX_MAIL_FLAG_DIRTY) != 0;
INDEX_KEYWORDS_BYTE_COUNT) != 0) {
const unsigned char *data;
if (from_line_size == 0)
int ret;
if (ret < 0)
if (ret > 0) {
if (seq == 0) {
seq++;
if (ret < 0) {
if (ret == 0) {
old_offset) < 0) {
uid = 0;
messages_count : 0);
&expunged) < 0)
if (size == 0)
if (ret <= 0)
return ret;
uid = 0;
if (uid != 0) {
if (ret < 0)
if (ret == 0)
uid = 0;
&rec) < 0)
&expunged) < 0)
if (!expunged) {
if (!expunged) {
rec) < 0)
if (!expunged) {
if (!partial)
int need_rewrite;
if (need_rewrite) {
trailer_size) < 0)
min_msg_count = 0;
if (ret <= 0) {
if (ret < 0)
FALSE);
if (ret <= 0) {
unsigned int lock_id = 0;
if (!changed)
lock_id = 0;
if (changed) {
if (ret <= 0) {
if (ret < 0)
if (lock_id != 0)
return ret;
if (lock_id != 0)
if (lock_id == 0) {
goto __again;
if (ret < 0)
if (ret < 0)
if (ret < 0)
&seq,
&offset) < 0) {
index_sync_ctx) < 0) {
unsigned int read_lock_id = 0;
return ret;
struct mailbox_sync_context *
int ret = 0;