mbox-sync-parse.c revision 1430ad83da079f60c8ad86abf398eaff9f34e97a
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (C) 2004 Timo Sirainen */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen/* MD5 header summing logic was pretty much copy&pasted from popa3d by
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen Solar Designer */
c96eb61168670cfdd7596baba18856d3f086a093Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "lib.h"
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen#include "buffer.h"
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#include "istream.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "str.h"
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen#include "write-full.h"
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen#include "message-parser.h"
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen#include "mail-index.h"
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen#include "mbox-storage.h"
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen#include "mbox-md5.h"
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen#include "mbox-sync-private.h"
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen#include <stdlib.h>
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen#define IS_LWSP_LF(c) (IS_LWSP(c) || (c) == '\n')
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainenstruct mbox_sync_header_func {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen const char *header;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen int (*func)(struct mbox_sync_mail_context *ctx,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct message_header_line *hdr);
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen};
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainenstruct mbox_flag_type mbox_status_flags[] = {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen { 'R', MAIL_SEEN },
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen { 'O', MBOX_NONRECENT },
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen { 0, 0 }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen};
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainenstruct mbox_flag_type mbox_xstatus_flags[] = {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen { 'A', MAIL_ANSWERED },
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen { 'F', MAIL_FLAGGED },
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen { 'T', MAIL_DRAFT },
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen { 'D', MAIL_DELETED },
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen { 0, 0 }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen};
150e64c376365becf1ec5c9d45912ecb840eea96Timo Sirainen
150e64c376365becf1ec5c9d45912ecb840eea96Timo Sirainenstatic void parse_trailing_whitespace(struct mbox_sync_mail_context *ctx,
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen struct message_header_line *hdr)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen size_t i, space = 0;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen /* the value may contain newlines. we can't count whitespace before
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen and after it as a single contiguous whitespace block, as that may
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen get us into situation where removing whitespace goes eg.
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen " \n \n" -> " \n\n" which would then be treated as end of headers.
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen that could probably be avoided by being careful, but as newlines
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen should never be there (we don't generate them), it's not worth the
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen trouble. */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen for (i = hdr->full_value_len; i > 0; i--) {
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen if (!IS_LWSP(hdr->full_value[i-1]))
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen break;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen space++;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if ((ssize_t)space > ctx->mail.space) {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen i_assert(space != 0);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ctx->mail.offset = hdr->full_value_offset + i;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ctx->mail.space = space;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic enum mail_flags mbox_flag_find(struct mbox_flag_type *flags, char chr)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen int i;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen for (i = 0; flags[i].chr != 0; i++) {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (flags[i].chr == chr)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return flags[i].flag;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return 0;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic void parse_status_flags(struct mbox_sync_mail_context *ctx,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct message_header_line *hdr,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct mbox_flag_type *flags_list)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen size_t i;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen for (i = 0; i < hdr->full_value_len; i++) {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ctx->mail.flags |=
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen mbox_flag_find(flags_list, hdr->full_value[i]);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic int parse_status(struct mbox_sync_mail_context *ctx,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct message_header_line *hdr)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen parse_status_flags(ctx, hdr, mbox_status_flags);
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen ctx->hdr_pos[MBOX_HDR_STATUS] = str_len(ctx->header);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return TRUE;
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic int parse_x_status(struct mbox_sync_mail_context *ctx,
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen struct message_header_line *hdr)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen parse_status_flags(ctx, hdr, mbox_xstatus_flags);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_STATUS] = str_len(ctx->header);
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen return TRUE;
303a87c31cb4aa198326694e231df53a043e63c7Timo Sirainen}
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainenstatic int parse_x_imap_base(struct mbox_sync_mail_context *ctx,
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen struct message_header_line *hdr)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen const char *str;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen char *end;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen size_t pos;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen uint32_t uid_validity, uid_last;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (ctx->seq != 1 || ctx->seen_imapbase) {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen /* Valid only in first message */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen return FALSE;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen /* <uid validity> <last uid> */
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen t_push();
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen str = t_strndup(hdr->full_value, hdr->full_value_len);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen uid_validity = strtoul(str, &end, 10);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen uid_last = strtoul(end, &end, 10);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen pos = end - str;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen t_pop();
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen while (pos < hdr->full_value_len && IS_LWSP_LF(hdr->full_value[pos]))
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen pos++;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (uid_validity == 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* broken */
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen return FALSE;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (ctx->sync_ctx->base_uid_validity == 0) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen ctx->sync_ctx->base_uid_validity = uid_validity;
39e6fcc3e8b1ccb13087c232cb6bdea04d1a20a4Timo Sirainen ctx->sync_ctx->base_uid_last = uid_last;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (ctx->sync_ctx->next_uid-1 <= uid_last)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen ctx->sync_ctx->next_uid = uid_last+1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen else {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen ctx->sync_ctx->update_base_uid_last =
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen ctx->sync_ctx->next_uid - 1;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen ctx->need_rewrite = TRUE;
bc3698b8892df8003b410daea6f5bbcd20433808Timo Sirainen }
06e72c658de3ce1252594b151313df90acf73271Timo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
06e72c658de3ce1252594b151313df90acf73271Timo Sirainen if (ctx->sync_ctx->next_uid <= ctx->sync_ctx->prev_msg_uid) {
06e72c658de3ce1252594b151313df90acf73271Timo Sirainen /* broken, update */
06e72c658de3ce1252594b151313df90acf73271Timo Sirainen ctx->sync_ctx->next_uid = ctx->sync_ctx->prev_msg_uid+1;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] = str_len(ctx->header);
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen ctx->seen_imapbase = TRUE;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (pos == hdr->full_value_len)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen return TRUE;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen // FIXME: save keywords
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen parse_trailing_whitespace(ctx, hdr);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return TRUE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen}
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenstatic int parse_x_imap(struct mbox_sync_mail_context *ctx,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct message_header_line *hdr)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (!parse_x_imap_base(ctx, hdr))
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return FALSE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen /* this is the c-client style "FOLDER INTERNAL DATA" message.
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen skip it. */
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen ctx->pseudo = TRUE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return TRUE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen}
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenstatic int parse_x_keywords(struct mbox_sync_mail_context *ctx,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct message_header_line *hdr)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen // FIXME: parse them
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen parse_trailing_whitespace(ctx, hdr);
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return TRUE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen}
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenstatic int parse_x_uid(struct mbox_sync_mail_context *ctx,
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct message_header_line *hdr)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen uint32_t value = 0;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen size_t i;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (ctx->mail.uid != 0) {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen /* duplicate */
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return FALSE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen }
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen for (i = 0; i < hdr->full_value_len; i++) {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (hdr->full_value[i] < '0' || hdr->full_value[i] > '9')
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen break;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen value = value*10 + (hdr->full_value[i] - '0');
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen }
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen for (; i < hdr->full_value_len; i++) {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen if (!IS_LWSP_LF(hdr->full_value[i])) {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen /* broken value */
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return FALSE;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen }
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen }
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
ccb77e2f63626ec46e5745ef4f38baa8e8e504fcTimo Sirainen if (ctx->sync_ctx != NULL) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (value >= ctx->sync_ctx->next_uid) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen /* next_uid broken - fix it */
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen ctx->sync_ctx->next_uid = value+1;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
bd74402ca1a39ec303075fefb1212d7e18a71531Timo Sirainen if (value <= ctx->sync_ctx->prev_msg_uid) {
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen /* broken - UIDs must be growing */
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen ctx->uid_broken = TRUE;
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen return FALSE;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen }
f5a24412980cb19b07cb0cd12dba75886f281875Timo Sirainen ctx->sync_ctx->prev_msg_uid = value;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen ctx->mail.uid = value;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
63f36c2b47217fc2dc4ed49cfc1907311d5ed366Timo Sirainen if (ctx->sync_ctx == NULL) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* we're in mbox_sync_parse_match_mail() */
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen return TRUE;
bd74402ca1a39ec303075fefb1212d7e18a71531Timo Sirainen }
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen
bd74402ca1a39ec303075fefb1212d7e18a71531Timo Sirainen if (ctx->sync_ctx->dest_first_mail && !ctx->seen_imapbase) {
bd74402ca1a39ec303075fefb1212d7e18a71531Timo Sirainen /* everything was good, except we can't have X-UID before
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen X-IMAPbase header (to keep c-client compatibility). keep
c6ae908f6a2313573625d782bdd4e0ff3882c44aTimo Sirainen the UID, but when we're rewriting this makes sure the
c6ae908f6a2313573625d782bdd4e0ff3882c44aTimo Sirainen X-UID is appended after X-IMAPbase. */
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen return FALSE;
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen }
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_UID] = str_len(ctx->header);
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen ctx->parsed_uid = value;
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen parse_trailing_whitespace(ctx, hdr);
17b03c9db961e1c004284907d969eb11b08a795eTimo Sirainen return TRUE;
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen}
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainenstatic int parse_content_length(struct mbox_sync_mail_context *ctx,
ef11d3930c3602fc86349a4e3a53442df470b601Timo Sirainen struct message_header_line *hdr)
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen{
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen uoff_t value = 0;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen size_t i;
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (ctx->content_length != (uoff_t)-1) {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen /* duplicate */
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return FALSE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen }
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen for (i = 0; i < hdr->full_value_len; i++) {
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen if (hdr->full_value[i] < '0' || hdr->full_value[i] > '9')
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen break;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen value = value*10 + (hdr->full_value[i] - '0');
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
ccb77e2f63626ec46e5745ef4f38baa8e8e504fcTimo Sirainen for (; i < hdr->full_value_len; i++) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (!IS_LWSP_LF(hdr->full_value[i])) {
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen /* broken value */
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return FALSE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen }
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen }
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen ctx->content_length = value;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen return TRUE;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen}
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainenstatic struct mbox_sync_header_func header_funcs[] = {
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen { "Content-Length", parse_content_length },
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen { "Status", parse_status },
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen { "X-IMAP", parse_x_imap },
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen { "X-IMAPbase", parse_x_imap_base },
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen { "X-Keywords", parse_x_keywords },
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen { "X-Status", parse_x_status },
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen { "X-UID", parse_x_uid }
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen};
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen#define HEADER_FUNCS_COUNT (sizeof(header_funcs) / sizeof(*header_funcs))
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainenstatic int mbox_sync_bsearch_header_func_cmp(const void *p1, const void *p2)
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen{
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen const char *key = p1;
ccd83028a34cc6e2b6370eb7ecf1cf25e717c2d3Timo Sirainen const struct mbox_sync_header_func *func = p2;
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen return strcasecmp(key, func->header);
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen}
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainenvoid mbox_sync_parse_next_mail(struct istream *input,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen struct mbox_sync_mail_context *ctx)
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen{
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen struct mbox_sync_context *sync_ctx = ctx->sync_ctx;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen struct message_header_parser_ctx *hdr_ctx;
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen struct message_header_line *hdr;
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen struct mbox_sync_header_func *func;
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen struct mbox_md5_context *mbox_md5_ctx;
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen size_t line_start_pos;
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen int i, ret;
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen ctx->hdr_offset = ctx->mail.offset;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen ctx->header_first_change = (size_t)-1;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen ctx->header_last_change = 0;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen for (i = 0; i < MBOX_HDR_COUNT; i++)
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen ctx->hdr_pos[i] = (size_t)-1;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen ctx->content_length = (uoff_t)-1;
28cd2599128e102198758cf6080588305feb6bcdTimo Sirainen str_truncate(ctx->header, 0);
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen mbox_md5_ctx = mbox_md5_init();
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen line_start_pos = 0;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen hdr_ctx = message_parse_header_init(input, NULL, FALSE);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen while ((ret = message_parse_header_next(hdr_ctx, &hdr)) > 0) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (hdr->eoh) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen ctx->have_eoh = TRUE;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen break;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (!hdr->continued) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen line_start_pos = str_len(ctx->header);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen str_append(ctx->header, hdr->name);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen str_append_n(ctx->header, hdr->middle, hdr->middle_len);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen func = bsearch(hdr->name, header_funcs,
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen HEADER_FUNCS_COUNT, sizeof(*header_funcs),
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen mbox_sync_bsearch_header_func_cmp);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (func != NULL) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (hdr->continues) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen hdr->use_full_value = TRUE;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen continue;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (!func->func(ctx, hdr)) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen /* this header is broken, remove it */
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen ctx->need_rewrite = TRUE;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen str_truncate(ctx->header, line_start_pos);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (ctx->header_first_change == (size_t)-1) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen ctx->header_first_change =
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen line_start_pos;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen continue;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen buffer_append(ctx->header, hdr->full_value,
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen hdr->full_value_len);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen } else {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen mbox_md5_continue(mbox_md5_ctx, hdr);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen buffer_append(ctx->header, hdr->value,
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen hdr->value_len);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (!hdr->no_newline)
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen str_append_c(ctx->header, '\n');
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen i_assert(ret != 0);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen message_parse_header_deinit(hdr_ctx);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen mbox_md5_finish(mbox_md5_ctx, ctx->hdr_md5_sum);
a4bc2c3962b94f83c7bb7bebe7af364f4dee7883Timo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen if ((ctx->seq == 1 && sync_ctx->base_uid_validity == 0) ||
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen (ctx->seq > 1 && sync_ctx->dest_first_mail)) {
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen /* missing X-IMAPbase */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen ctx->need_rewrite = TRUE;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (ctx->seq == 1 && sync_ctx->update_base_uid_last != 0 &&
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen sync_ctx->update_base_uid_last > sync_ctx->base_uid_last) {
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen /* update uid-last field in X-IMAPbase */
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen ctx->need_rewrite = TRUE;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen ctx->body_offset = input->v_offset;
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen}
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainenint mbox_sync_parse_match_mail(struct index_mailbox *ibox,
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen struct mail_index_view *view, uint32_t seq)
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen{
10cfe8a2bdc5ccfc05380689c71c27209327538fTimo Sirainen struct mbox_sync_mail_context ctx;
10cfe8a2bdc5ccfc05380689c71c27209327538fTimo Sirainen struct message_header_parser_ctx *hdr_ctx;
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen struct message_header_line *hdr;
10cfe8a2bdc5ccfc05380689c71c27209327538fTimo Sirainen struct header_func *func;
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen struct mbox_md5_context *mbox_md5_ctx;
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen const void *data;
a54be2bd26d6f0860d194d3aeedfa6b7fc14d24cTimo Sirainen uint32_t uid;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen int ret;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen /* we only wish to be sure that this mail actually is what we expect
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen it to be. If there's X-UID header, it's used. Otherwise use
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen the MD5 sum. */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen memset(&ctx, 0, sizeof(ctx));
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen mbox_md5_ctx = mbox_md5_init();
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen hdr_ctx = message_parse_header_init(ibox->mbox_stream, NULL, FALSE);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen while ((ret = message_parse_header_next(hdr_ctx, &hdr)) > 0) {
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen if (hdr->eoh)
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen break;
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen
8039af9679af6fb56116b353fe44f7dd4c08f031Timo Sirainen func = bsearch(hdr->name, header_funcs,
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen HEADER_FUNCS_COUNT, sizeof(*header_funcs),
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen mbox_sync_bsearch_header_func_cmp);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen if (func != NULL) {
e30e068c8fac372ae217b3b31791a0c8c8046b7fTimo Sirainen if (strcasecmp(hdr->name, "X-UID") == 0) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (hdr->continues) {
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen hdr->use_full_value = TRUE;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen continue;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen (void)parse_x_uid(&ctx, hdr);
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen if (ctx.mail.uid != 0)
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen break;
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen }
923eb3dde28e4d8841c14fd6b4a69635b7070c3eTimo Sirainen } else {
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen mbox_md5_continue(mbox_md5_ctx, hdr);
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen }
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen }
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen i_assert(ret != 0);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen message_parse_header_deinit(hdr_ctx);
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen
88286b0527bcc0711e312e9db65ca121a45213e3Timo Sirainen mbox_md5_finish(mbox_md5_ctx, ctx.hdr_md5_sum);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
c4267cf4c40fb1f866b5958ff122ef836b8c5dfbTimo Sirainen if (ctx.mail.uid != 0) {
68efcccb384f2d6871164b072457e87473502c51Timo Sirainen /* match by X-UID header */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen if (mail_index_lookup_uid(view, seq, &uid) < 0) {
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen mail_storage_set_index_error(ibox);
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen return -1;
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen }
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen return ctx.mail.uid == uid;
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen }
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen /* match by MD5 sum */
d42c9a8f362b76740418c4f9f9441eb7fc661e57Timo Sirainen ibox->mbox_save_md5 = TRUE;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen if (mail_index_lookup_ext(view, seq, ibox->md5hdr_ext_idx, &data) < 0) {
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen mail_storage_set_index_error(ibox);
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen return -1;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen }
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen return data == NULL ? 0 :
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen memcmp(data, ctx.hdr_md5_sum, 16) == 0;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen}
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen