mbox-sync-update.c revision dc049c5e83d947aaf1b97c26ae819cc9577e0475
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen/* Copyright (C) 2004 Timo Sirainen */
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen#include "ioloop.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "message-parser.h"
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen#include "index-storage.h"
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen#include "mbox-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mbox-sync-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void status_flags_append(struct mbox_sync_mail_context *ctx,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const struct mbox_flag_type *flags_list)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; flags_list[i].chr != 0; i++) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(ctx->header, flags_list[i].chr);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainenvoid mbox_sync_move_buffer(struct mbox_sync_mail_context *ctx,
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen size_t pos, size_t need, size_t have)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen{
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen ssize_t diff = (ssize_t)need - (ssize_t)have;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen int i;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen i_assert(have < SSIZE_T_MAX);
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen if (diff == 0) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (ctx->header_last_change < pos + have ||
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->header_last_change == (size_t)-1)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->header_last_change = pos + have;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen } else {
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen /* FIXME: if (diff < ctx->space && pos < ctx->offset) then
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen move the data only up to space offset and give/take the
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen space from there. update header_last_change accordingly.
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen (except pos and offset can't be compared directly) */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->header_last_change = (size_t)-1;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen for (i = 0; i < MBOX_HDR_COUNT; i++) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (ctx->hdr_pos[i] > pos &&
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->hdr_pos[i] != (size_t)-1)
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen ctx->hdr_pos[i] += diff;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen if (diff < 0)
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen str_delete(ctx->header, pos, -diff);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen else {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->header_last_change = (size_t)-1;
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen buffer_copy(ctx->header, pos + diff,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->header, pos, (size_t)-1);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void status_flags_replace(struct mbox_sync_mail_context *ctx, size_t pos,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen const struct mbox_flag_type *flags_list)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen unsigned char *data;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen size_t size;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen int i, need, have;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if (ctx->header_first_change > pos)
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen ctx->header_first_change = pos;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* how many bytes do we need? */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (i = 0, need = 0; flags_list[i].chr != 0; i++) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen need++;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* how many bytes do we have now? */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen data = buffer_get_modifyable_data(ctx->header, &size);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (have = 0; pos < size; pos++) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (data[pos] == '\n')
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* see if this is unknown flag for us */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (i = 0; flags_list[i].chr != 0; i++) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (flags_list[i].chr == data[pos])
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if (flags_list[i].chr != 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen have++;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen else {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* save this one */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen data[pos-have] = data[pos];
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen pos -= have;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen mbox_sync_move_buffer(ctx, pos, need, have);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* @UNSAFE */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen data = buffer_get_space_unsafe(ctx->header, pos, need);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (i = 0, need = 0; flags_list[i].chr != 0; i++) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen *data++ = flags_list[i].chr;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void keywords_append(struct mbox_sync_mail_context *ctx,
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen keywords_mask_t keywords)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen // FIXME
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mbox_sync_add_missing_headers(struct mbox_sync_mail_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t old_hdr_size, new_hdr_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int i, have_keywords;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen old_hdr_size = ctx->body_offset - ctx->hdr_offset;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen new_hdr_size = str_len(ctx->header);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen if (new_hdr_size > 0 &&
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen str_data(ctx->header)[new_hdr_size-1] != '\n') {
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen /* broken header - doesn't end with \n. fix it. */
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen str_append_c(ctx->header, '\n');
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen }
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen if (ctx->sync_ctx->dest_first_mail &&
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (ctx->sync_ctx->base_uid_validity == 0) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ctx->sync_ctx->base_uid_validity =
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ctx->sync_ctx->hdr->uid_validity == 0 ?
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen (uint32_t)ioloop_time :
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen ctx->sync_ctx->hdr->uid_validity;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen str_append(ctx->header, "X-IMAPbase: ");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] = str_len(ctx->header);
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen str_printfa(ctx->header, "%u %010u",
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen ctx->sync_ctx->base_uid_validity,
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen ctx->sync_ctx->next_uid-1);
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen //FIXME:keywords_append(ctx, all_keywords);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(ctx->header, '\n');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
907723f35f4d3dfc774ca42d00a8a7b8ef90dd5dTimo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_UID] == (size_t)-1 && !ctx->pseudo) {
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen str_append(ctx->header, "X-UID: ");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_UID] = str_len(ctx->header);
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen str_printfa(ctx->header, "%u\n", ctx->mail.uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_STATUS] == (size_t)-1 &&
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (ctx->mail.flags & STATUS_FLAGS_MASK) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(ctx->header, "Status: ");
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen ctx->hdr_pos[MBOX_HDR_STATUS] = str_len(ctx->header);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen status_flags_append(ctx, mbox_status_flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(ctx->header, '\n');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_STATUS] == (size_t)-1 &&
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (ctx->mail.flags & XSTATUS_FLAGS_MASK) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(ctx->header, "X-Status: ");
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_STATUS] = str_len(ctx->header);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen status_flags_append(ctx, mbox_xstatus_flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(ctx->header, '\n');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen have_keywords = FALSE;
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (ctx->mail.keywords[i] != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen have_keywords = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] == (size_t)-1 && have_keywords) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append(ctx->header, "X-Keywords: ");
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen keywords_append(ctx, ctx->mail.keywords);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(ctx->header, '\n');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen if (ctx->content_length == (uoff_t)-1 &&
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen ctx->mail.body_size >= MBOX_MIN_CONTENT_LENGTH_SIZE) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(ctx->header, "Content-Length: %"PRIuUOFF_T"\n",
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ctx->mail.body_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (str_len(ctx->header) != new_hdr_size) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->header_first_change == (size_t)-1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->header_first_change = new_hdr_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->header_last_change = (size_t)-1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->have_eoh)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_append_c(ctx->header, '\n');
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mbox_sync_update_status(struct mbox_sync_mail_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (ctx->hdr_pos[MBOX_HDR_STATUS] != (size_t)-1) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen status_flags_replace(ctx, ctx->hdr_pos[MBOX_HDR_STATUS],
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mbox_status_flags);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mbox_sync_update_xstatus(struct mbox_sync_mail_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_STATUS] != (size_t)-1) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen status_flags_replace(ctx, ctx->hdr_pos[MBOX_HDR_X_STATUS],
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mbox_xstatus_flags);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mbox_sync_update_xkeywords(struct mbox_sync_mail_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenstatic void mbox_sync_update_line(struct mbox_sync_mail_context *ctx,
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen size_t pos, string_t *new_line)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen{
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen const char *hdr, *p;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ctx->header_first_change > pos)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ctx->header_first_change = pos;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen hdr = str_c(ctx->header) + pos;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen p = strchr(hdr, '\n');
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (p == NULL) {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen /* shouldn't really happen, but allow anyway.. */
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ctx->header_last_change = (size_t)-1;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen str_truncate(ctx->header, pos);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen str_append_str(ctx->header, new_line);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen } else {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen mbox_sync_move_buffer(ctx, pos, str_len(new_line), p - hdr + 1);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen buffer_copy(ctx->header, pos, new_line, 0, (size_t)-1);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen }
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen}
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainenstatic void mbox_sync_update_x_imap_base(struct mbox_sync_mail_context *ctx)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen{
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen string_t *str;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
325f4573edfa5b751832ac01023f3e81be992bf0Timo Sirainen if (!ctx->sync_ctx->dest_first_mail ||
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1 ||
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->sync_ctx->update_base_uid_last == 0 ||
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->sync_ctx->update_base_uid_last < ctx->sync_ctx->base_uid_last)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* update uid-last field in X-IMAPbase */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen t_push();
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen str = t_str_new(200);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen str_printfa(str, "%u %010u", ctx->sync_ctx->base_uid_validity,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ctx->sync_ctx->update_base_uid_last);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen //FIXME:keywords_append(ctx, all_keywords);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen str_append_c(str, '\n');
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_IMAPBASE], str);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen t_pop();
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen}
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenstatic void mbox_sync_update_x_uid(struct mbox_sync_mail_context *ctx)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen{
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen string_t *str;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_UID] == (size_t)-1 ||
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen ctx->mail.uid == ctx->parsed_uid)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen return;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen t_push();
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen str = t_str_new(64);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen str_printfa(str, "%u", ctx->mail.uid);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_UID], str);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen t_pop();
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mbox_sync_update_header(struct mbox_sync_mail_context *ctx,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen buffer_t *syncs_buf)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const struct mail_index_sync_rec *sync;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen size_t size, i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t old_flags;
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen keywords_mask_t old_keywords;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sync = buffer_get_data(syncs_buf, &size);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen size /= sizeof(*sync);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen old_flags = ctx->mail.flags;
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen if ((ctx->mail.flags & MBOX_NONRECENT) == 0 &&
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen !ctx->sync_ctx->ibox->keep_recent)
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen ctx->mail.flags |= MBOX_NONRECENT;
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (size != 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen memcpy(old_keywords, ctx->mail.keywords, sizeof(old_keywords));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (i = 0; i < size; i++) {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if (sync[i].type != MAIL_INDEX_SYNC_TYPE_FLAGS)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen continue;
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mail_index_sync_flags_apply(&sync[i], &ctx->mail.flags,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ctx->mail.keywords);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen /* keep our old recent flag. especially because we use it
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen negatively as non-recent */
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen ctx->mail.flags = (ctx->mail.flags & ~MAIL_RECENT) |
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen (old_flags & MAIL_RECENT);
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((old_flags & XSTATUS_FLAGS_MASK) !=
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (ctx->mail.flags & XSTATUS_FLAGS_MASK))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mbox_sync_update_xstatus(ctx);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (memcmp(old_keywords, ctx->mail.keywords,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen INDEX_KEYWORDS_BYTE_COUNT) != 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mbox_sync_update_xkeywords(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen if ((old_flags & STATUS_FLAGS_MASK) !=
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen (ctx->mail.flags & STATUS_FLAGS_MASK))
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen mbox_sync_update_status(ctx);
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen mbox_sync_update_x_imap_base(ctx);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen mbox_sync_update_x_uid(ctx);
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen mbox_sync_add_missing_headers(ctx);
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen ctx->updated = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenvoid mbox_sync_update_header_from(struct mbox_sync_mail_context *ctx,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const struct mbox_sync_mail *mail)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if ((ctx->mail.flags & STATUS_FLAGS_MASK) !=
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen (mail->flags & STATUS_FLAGS_MASK) ||
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen (ctx->mail.flags & MBOX_NONRECENT) == 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ctx->mail.flags = (ctx->mail.flags & ~STATUS_FLAGS_MASK) |
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen (mail->flags & STATUS_FLAGS_MASK);
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen if (!ctx->sync_ctx->ibox->keep_recent)
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen ctx->mail.flags |= MBOX_NONRECENT;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mbox_sync_update_status(ctx);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if ((ctx->mail.flags & XSTATUS_FLAGS_MASK) !=
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (mail->flags & XSTATUS_FLAGS_MASK)) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ctx->mail.flags = (ctx->mail.flags & ~XSTATUS_FLAGS_MASK) |
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (mail->flags & XSTATUS_FLAGS_MASK);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mbox_sync_update_xstatus(ctx);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (memcmp(ctx->mail.keywords, mail->keywords,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen INDEX_KEYWORDS_BYTE_COUNT) != 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen memcpy(ctx->mail.keywords, mail->keywords,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen INDEX_KEYWORDS_BYTE_COUNT);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mbox_sync_update_xkeywords(ctx);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen i_assert(ctx->mail.uid == 0 || ctx->mail.uid == mail->uid);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ctx->mail.uid = mail->uid;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen mbox_sync_update_x_imap_base(ctx);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen mbox_sync_update_x_uid(ctx);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mbox_sync_add_missing_headers(ctx);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}