mbox-sync-update.c revision 08fa343b3aace9343da3195686c65c5326eda207
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (C) 2004 Timo Sirainen */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "lib.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "ioloop.h"
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi#include "buffer.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "str.h"
5d60e31c7b701b606067a20bc88dcc8a6de7bbd6Timo Sirainen#include "message-parser.h"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#include "index-storage.h"
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen#include "mbox-storage.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "mbox-sync-private.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void status_flags_append(struct mbox_sync_mail_context *ctx,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct mbox_flag_type *flags_list)
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen{
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen int i;
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen for (i = 0; flags_list[i].chr != 0; i++) {
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen str_append_c(ctx->header, flags_list[i].chr);
daa7e7459749ae8f82cd3eed9c44522d81c609a3Timo Sirainen }
46ec5983bf4519ea42dbfcae3d7c62be0d8ef95fTimo Sirainen}
bbadd5331f534017cf62d5183003b3d9fdad079eTimo Sirainen
6523f54d1521edf894880f2d45e75cef5dd31c3dTimo Sirainenvoid mbox_sync_move_buffer(struct mbox_sync_mail_context *ctx,
72f5f2c5c6905b5d3f389b424313e2c450dfad96Timo Sirainen size_t pos, size_t need, size_t have)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen ssize_t diff = (ssize_t)need - (ssize_t)have;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen int i;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen i_assert(have < SSIZE_T_MAX);
373492be949e159fda651807b3acda2c5c077027Timo Sirainen
bbadd5331f534017cf62d5183003b3d9fdad079eTimo Sirainen if (diff == 0) {
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch if (ctx->header_last_change < pos + have ||
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch ctx->header_last_change == (size_t)-1)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen ctx->header_last_change = pos + have;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen } else {
da7f1a07f583df8905684a7b78469960afd7c78dPhil Carmody /* FIXME: if (diff < ctx->space && pos < ctx->offset) then
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen move the data only up to space offset and give/take the
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen space from there. update header_last_change accordingly.
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen (except pos and offset can't be compared directly) */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen ctx->header_last_change = (size_t)-1;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen for (i = 0; i < MBOX_HDR_COUNT; i++) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (ctx->hdr_pos[i] > pos &&
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ctx->hdr_pos[i] != (size_t)-1)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ctx->hdr_pos[i] += diff;
635df5b4cbcd7b24c825e01d9dd66d3a4274c4c7Timo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (diff < 0)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str_delete(ctx->header, pos, -diff);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen else {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ctx->header_last_change = (size_t)-1;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen buffer_copy(ctx->header, pos + diff,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ctx->header, pos, (size_t)-1);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
51fb710488efa419a2964335c30451c62b9633b1Timo Sirainen}
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
93a7d1ee4b518b5c85f9721dc6539e4dab6aae00Timo Sirainenstatic void status_flags_replace(struct mbox_sync_mail_context *ctx, size_t pos,
f7f25f9e1a38678d0e97d2e609beac16285fac6bTimo Sirainen const struct mbox_flag_type *flags_list)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen{
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen unsigned char *data;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen size_t size;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen int i, need, have;
35fcdde46a71ac151c2518d48c841019f1181bb2Timo Sirainen
35fcdde46a71ac151c2518d48c841019f1181bb2Timo Sirainen if (ctx->header_first_change > pos)
35fcdde46a71ac151c2518d48c841019f1181bb2Timo Sirainen ctx->header_first_change = pos;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen /* how many bytes do we need? */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen for (i = 0, need = 0; flags_list[i].chr != 0; i++) {
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
635df5b4cbcd7b24c825e01d9dd66d3a4274c4c7Timo Sirainen need++;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen }
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen /* how many bytes do we have now? */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen data = buffer_get_modifyable_data(ctx->header, &size);
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen for (have = 0; pos < size; pos++) {
da7f1a07f583df8905684a7b78469960afd7c78dPhil Carmody if (data[pos] == '\n')
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen break;
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen /* see if this is unknown flag for us */
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen for (i = 0; flags_list[i].chr != 0; i++) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (flags_list[i].chr == data[pos])
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen break;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (flags_list[i].chr != 0)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen have++;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen else {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* save this one */
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen data[pos-have] = data[pos];
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen pos -= have;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen mbox_sync_move_buffer(ctx, pos, need, have);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* @UNSAFE */
ba8498efbf886ca8b69fdb20c0ba2f5dba9416e3Timo Sirainen data = buffer_get_space_unsafe(ctx->header, pos, need);
93a7d1ee4b518b5c85f9721dc6539e4dab6aae00Timo Sirainen for (i = 0, need = 0; flags_list[i].chr != 0; i++) {
f7f25f9e1a38678d0e97d2e609beac16285fac6bTimo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen *data++ = flags_list[i].chr;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen}
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainenstatic void keywords_append(struct mbox_sync_mail_context *ctx,
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen keywords_mask_t keywords)
9f0f2de10e4ea0c99052bf4b2bef8179f2536228Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen // FIXME
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void mbox_sync_add_missing_headers(struct mbox_sync_mail_context *ctx)
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen{
544a727de8ab0e6c55cab18a7ee475fffdf5eff3Timo Sirainen size_t old_hdr_size, new_hdr_size;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen int i, have_keywords;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen old_hdr_size = ctx->body_offset - ctx->hdr_offset;
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen new_hdr_size = str_len(ctx->header);
10f6f2224c897fc543973efd2f46b86a3ab1148dAki Tuomi
268a76700330d159c805c70d1e3eae2e21f1cb9eAki Tuomi if (new_hdr_size > 0 &&
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen str_data(ctx->header)[new_hdr_size-1] != '\n') {
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen /* broken header - doesn't end with \n. fix it. */
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen str_append_c(ctx->header, '\n');
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen }
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen if (ctx->sync_ctx->dest_first_mail &&
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1) {
380dbb60ae291cbe39d1f710284562ca9167150bTimo Sirainen if (ctx->sync_ctx->base_uid_validity == 0) {
380dbb60ae291cbe39d1f710284562ca9167150bTimo Sirainen ctx->sync_ctx->base_uid_validity =
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen ctx->sync_ctx->hdr->uid_validity == 0 ?
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (uint32_t)ioloop_time :
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->sync_ctx->hdr->uid_validity;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
1b823b2b7790a1e1b7974fcf11a4c48a28e70f37Timo Sirainen str_append(ctx->header, "X-IMAPbase: ");
544a727de8ab0e6c55cab18a7ee475fffdf5eff3Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] = str_len(ctx->header);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen str_printfa(ctx->header, "%u %010u",
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen ctx->sync_ctx->base_uid_validity,
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen ctx->sync_ctx->next_uid-1);
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen //FIXME:keywords_append(ctx, all_keywords);
10f6f2224c897fc543973efd2f46b86a3ab1148dAki Tuomi str_append_c(ctx->header, '\n');
268a76700330d159c805c70d1e3eae2e21f1cb9eAki Tuomi }
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_UID] == (size_t)-1 && !ctx->pseudo) {
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen str_append(ctx->header, "X-UID: ");
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_UID] = str_len(ctx->header);
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen str_printfa(ctx->header, "%u\n", ctx->mail.uid);
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen }
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen if (ctx->hdr_pos[MBOX_HDR_STATUS] == (size_t)-1 &&
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen (ctx->mail.flags & STATUS_FLAGS_MASK) != 0) {
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen str_append(ctx->header, "Status: ");
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen ctx->hdr_pos[MBOX_HDR_STATUS] = str_len(ctx->header);
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen status_flags_append(ctx, mbox_status_flags);
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen str_append_c(ctx->header, '\n');
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
1b823b2b7790a1e1b7974fcf11a4c48a28e70f37Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_STATUS] == (size_t)-1 &&
544a727de8ab0e6c55cab18a7ee475fffdf5eff3Timo Sirainen (ctx->mail.flags & XSTATUS_FLAGS_MASK) != 0) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen str_append(ctx->header, "X-Status: ");
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_STATUS] = str_len(ctx->header);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen status_flags_append(ctx, mbox_xstatus_flags);
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen str_append_c(ctx->header, '\n');
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen }
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen have_keywords = FALSE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ctx->mail.keywords[i] != 0) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen have_keywords = TRUE;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen break;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen }
544a727de8ab0e6c55cab18a7ee475fffdf5eff3Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] == (size_t)-1 && have_keywords) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_append(ctx->header, "X-Keywords: ");
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header);
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen keywords_append(ctx, ctx->mail.keywords);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_append_c(ctx->header, '\n');
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen }
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen if (ctx->content_length == (uoff_t)-1 &&
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen ctx->mail.body_size >= MBOX_MIN_CONTENT_LENGTH_SIZE) {
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen str_printfa(ctx->header, "Content-Length: %"PRIuUOFF_T"\n",
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen ctx->mail.body_size);
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (str_len(ctx->header) != new_hdr_size) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ctx->header_first_change == (size_t)-1)
1b823b2b7790a1e1b7974fcf11a4c48a28e70f37Timo Sirainen ctx->header_first_change = new_hdr_size;
74fb6b5a156c5a61bb6ec827089bb142a10547ddTimo Sirainen ctx->header_last_change = (size_t)-1;
544a727de8ab0e6c55cab18a7ee475fffdf5eff3Timo Sirainen }
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen if (ctx->have_eoh)
04052d7cacaa866a3f00afb4e104fa46c04c1dd7Timo Sirainen str_append_c(ctx->header, '\n');
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen}
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainenstatic void mbox_sync_update_status(struct mbox_sync_mail_context *ctx)
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen{
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_STATUS] != (size_t)-1) {
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen status_flags_replace(ctx, ctx->hdr_pos[MBOX_HDR_STATUS],
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen mbox_status_flags);
b484ab4b55b0d5341f2f4dd98a655a75f0bf1275Timo Sirainen }
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen}
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainenstatic void mbox_sync_update_xstatus(struct mbox_sync_mail_context *ctx)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen{
1b823b2b7790a1e1b7974fcf11a4c48a28e70f37Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_STATUS] != (size_t)-1) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen status_flags_replace(ctx, ctx->hdr_pos[MBOX_HDR_X_STATUS],
544a727de8ab0e6c55cab18a7ee475fffdf5eff3Timo Sirainen mbox_xstatus_flags);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainenstatic void mbox_sync_update_xkeywords(struct mbox_sync_mail_context *ctx)
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen{
9dd1c256910f1fb42823116a641e7edb3ad11970Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void mbox_sync_update_line(struct mbox_sync_mail_context *ctx,
57d2429fae575e96ca276355af675deb66b76d00Timo Sirainen size_t pos, string_t *new_line)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
401b0787fff2dc986a5321ddb32acb1947ff66b0Timo Sirainen const char *hdr, *p;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ctx->header_first_change > pos)
57d2429fae575e96ca276355af675deb66b76d00Timo Sirainen ctx->header_first_change = pos;
401b0787fff2dc986a5321ddb32acb1947ff66b0Timo Sirainen
401b0787fff2dc986a5321ddb32acb1947ff66b0Timo Sirainen hdr = str_c(ctx->header) + pos;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen p = strchr(hdr, '\n');
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (p == NULL) {
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen /* shouldn't really happen, but allow anyway.. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->header_last_change = (size_t)-1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_truncate(ctx->header, pos);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_append_str(ctx->header, new_line);
61618d4c58080570f689614fec204ae14e90cef2Timo Sirainen } else {
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen mbox_sync_move_buffer(ctx, pos, str_len(new_line), p - hdr + 1);
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen buffer_copy(ctx->header, pos, new_line, 0, (size_t)-1);
e42b74025f8d02ee7aa476897a3f44e25bb8fc10Aki Tuomi }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void mbox_sync_update_x_imap_base(struct mbox_sync_mail_context *ctx)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen string_t *str;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (!ctx->sync_ctx->dest_first_mail ||
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1 ||
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen ctx->sync_ctx->update_base_uid_last == 0 ||
50e20db49f29917fe9adcf1b56b11badf28bd0e4Timo Sirainen ctx->sync_ctx->update_base_uid_last < ctx->sync_ctx->base_uid_last)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return;
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi /* update uid-last field in X-IMAPbase */
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi t_push();
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi str = t_str_new(200);
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi str_printfa(str, "%u %010u", ctx->sync_ctx->base_uid_validity,
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi ctx->sync_ctx->update_base_uid_last);
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi //FIXME:keywords_append(ctx, all_keywords);
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi str_append_c(str, '\n');
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_IMAPBASE], str);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen t_pop();
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
4addfd26372c6ae32ec93252696d86fd32081327Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void mbox_sync_update_x_uid(struct mbox_sync_mail_context *ctx)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen string_t *str;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_UID] == (size_t)-1 ||
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->mail.uid == ctx->parsed_uid)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen t_push();
1da01eaa962be13cee75771064e2256b1a82d90aTimo Sirainen str = t_str_new(64);
401b0787fff2dc986a5321ddb32acb1947ff66b0Timo Sirainen str_printfa(str, "%u", ctx->mail.uid);
f01eb1f51d618633c0189be9ab60a774f47fb7dfTimo Sirainen mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_UID], str);
f01eb1f51d618633c0189be9ab60a774f47fb7dfTimo Sirainen t_pop();
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen}
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen
401b0787fff2dc986a5321ddb32acb1947ff66b0Timo Sirainenvoid mbox_sync_update_header(struct mbox_sync_mail_context *ctx,
317689976ad393ab9eb78e7d9399fe3d899912adAki Tuomi buffer_t *syncs_buf)
317689976ad393ab9eb78e7d9399fe3d899912adAki Tuomi{
317689976ad393ab9eb78e7d9399fe3d899912adAki Tuomi const struct mail_index_sync_rec *sync;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen size_t size, i;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen uint8_t old_flags;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen keywords_mask_t old_keywords;
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen sync = buffer_get_data(syncs_buf, &size);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen size /= sizeof(*sync);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen old_flags = ctx->mail.flags;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
f2df3069766c747cbf020fea5d3a4261949064b0Timo Sirainen if (size != 0) {
e42b74025f8d02ee7aa476897a3f44e25bb8fc10Aki Tuomi memcpy(old_keywords, ctx->mail.keywords, sizeof(old_keywords));
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen for (i = 0; i < size; i++) {
062ea54b7775d0c92ed67b9b1f4d93fa8ec80c84Timo Sirainen if (sync[i].type != MAIL_INDEX_SYNC_TYPE_FLAGS)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen continue;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen mail_index_sync_flags_apply(&sync[i], &ctx->mail.flags,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ctx->mail.keywords);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen /* keep our old recent flag. especially because we use it
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen negatively as non-recent */
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi ctx->mail.flags = (ctx->mail.flags & ~MAIL_RECENT) |
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi (old_flags & MAIL_RECENT);
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi if ((old_flags & XSTATUS_FLAGS_MASK) !=
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi (ctx->mail.flags & XSTATUS_FLAGS_MASK))
31cc2948968dd56af45be1571e2e425f58e7e159Aki Tuomi mbox_sync_update_xstatus(ctx);
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi if (memcmp(old_keywords, ctx->mail.keywords,
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi INDEX_KEYWORDS_BYTE_COUNT) != 0)
203bb272804e4394ae07103cdc8ce67041ba21a1Aki Tuomi mbox_sync_update_xkeywords(ctx);
44cf91b7a701a9b4d9f59a990552eab4f7f64fbcTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (!ctx->sync_ctx->ibox->keep_recent)
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ctx->mail.flags |= MBOX_NONRECENT;
4addfd26372c6ae32ec93252696d86fd32081327Timo Sirainen
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if ((old_flags & STATUS_FLAGS_MASK) !=
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen (ctx->mail.flags & STATUS_FLAGS_MASK))
317689976ad393ab9eb78e7d9399fe3d899912adAki Tuomi mbox_sync_update_status(ctx);
317689976ad393ab9eb78e7d9399fe3d899912adAki Tuomi
317689976ad393ab9eb78e7d9399fe3d899912adAki Tuomi mbox_sync_update_x_imap_base(ctx);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen mbox_sync_update_x_uid(ctx);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen mbox_sync_add_missing_headers(ctx);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen ctx->updated = TRUE;
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen}
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen
401b0787fff2dc986a5321ddb32acb1947ff66b0Timo Sirainenvoid mbox_sync_update_header_from(struct mbox_sync_mail_context *ctx,
401b0787fff2dc986a5321ddb32acb1947ff66b0Timo Sirainen const struct mbox_sync_mail *mail)
1da01eaa962be13cee75771064e2256b1a82d90aTimo Sirainen{
f01eb1f51d618633c0189be9ab60a774f47fb7dfTimo Sirainen if ((ctx->mail.flags & STATUS_FLAGS_MASK) !=
f01eb1f51d618633c0189be9ab60a774f47fb7dfTimo Sirainen (mail->flags & STATUS_FLAGS_MASK) ||
f01eb1f51d618633c0189be9ab60a774f47fb7dfTimo Sirainen (ctx->mail.flags & MBOX_NONRECENT) == 0) {
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen ctx->mail.flags = (ctx->mail.flags & ~STATUS_FLAGS_MASK) |
ca5b3ec5331545b46ec1f1c4ecfa1302ddb10653Timo Sirainen (mail->flags & STATUS_FLAGS_MASK);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (!ctx->sync_ctx->ibox->keep_recent)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->mail.flags |= MBOX_NONRECENT;
7744586e3e0fd60158abfbb03a233d3bd8d6c48bTimo Sirainen mbox_sync_update_status(ctx);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if ((ctx->mail.flags & XSTATUS_FLAGS_MASK) !=
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen (mail->flags & XSTATUS_FLAGS_MASK)) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->mail.flags = (ctx->mail.flags & ~XSTATUS_FLAGS_MASK) |
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen (mail->flags & XSTATUS_FLAGS_MASK);
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen mbox_sync_update_xstatus(ctx);
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen }
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen if (memcmp(ctx->mail.keywords, mail->keywords,
383d0e8c24451468d6bea17e4b55d74de744abe6Timo Sirainen INDEX_KEYWORDS_BYTE_COUNT) != 0) {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen memcpy(ctx->mail.keywords, mail->keywords,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen INDEX_KEYWORDS_BYTE_COUNT);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mbox_sync_update_xkeywords(ctx);
d477acb83e14a776ece4ca94dcd1869e75d0c6eeTimo Sirainen }
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen i_assert(ctx->mail.uid == 0 || ctx->mail.uid == mail->uid);
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen ctx->mail.uid = mail->uid;
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen mbox_sync_update_x_imap_base(ctx);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen mbox_sync_update_x_uid(ctx);
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen mbox_sync_add_missing_headers(ctx);
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen}
738cfeb96c4b9cd92aa3c791d77734c2745cdd1aTimo Sirainen