mbox-sync.c revision 26687b22a471df9c28ce7bf233e7128e9d85f64c
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen/* Copyright (C) 2004 Timo Sirainen */
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen Modifying mbox can be slow, so we try to do it all at once minimizing the
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen required disk I/O. We may need to:
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen - Update message flags in Status, X-Status and X-Keywords headers
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen - Write missing X-UID and X-IMAPbase headers
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen - Write missing or broken Content-Length header if there's space
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen - Expunge specified messages
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen Here's how we do it:
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen - Start reading the mails mail headers from the beginning
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen - X-Keywords and X-UID headers may contain extra spaces at the end of them,
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen remember how much extra each message has and offset to beginning of the
#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>
dest++;
for (i = 0; i < size; i++) {
return TRUE;
return FALSE;
int ret;
sizeof(*sync_rec));
if (ret < 0) {
if (ret == 0) {
if (!*sync_expunge_r)
for (i = 0; i < size; i++) {
const void *data;
&data) < 0) {
int nocheck)
if (!nocheck) {
&offset) < 0)
INDEX_KEYWORDS_BYTE_COUNT) != 0) {
const unsigned char *data;
if (from_line_size == 0)
&offset);
int ret;
if (ret == 0)
int ret;
return ret;
int ret;
return ret;
if (ret > 0) {
return ret;
if (seq == 0)
if (min_message_count != 0) {
&expunged) < 0)
if (size == 0)
if (!expunged) {
if (ret < 0) {
return ret;
if (!expunged) {
rec) < 0)
if (!expunged) {
trailer_size) < 0)
int ret;
FALSE);
unsigned int lock_id = 0;
if (lock) {
if (lock)
if (last_commit) {
if (ret <= 0) {
if (ret < 0)
return ret;
lock_id = 0;
if (ret < 0)
if (ret < 0)
&seq,
&offset) < 0) {
return ret;