Lines Matching refs:sync_ctx
67 void mbox_sync_set_critical(struct mbox_sync_context *sync_ctx,
72 sync_ctx->errors = TRUE;
73 if (sync_ctx->ext_modified) {
74 mailbox_set_critical(&sync_ctx->mbox->box,
80 mailbox_set_critical(&sync_ctx->mbox->box,
86 int mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset)
88 if (istream_raw_mbox_seek(sync_ctx->input, from_offset) < 0) {
89 mbox_sync_set_critical(sync_ctx,
97 void mbox_sync_file_update_ext_modified(struct mbox_sync_context *sync_ctx)
103 if (fstat(sync_ctx->write_fd, &st) < 0) {
104 mbox_set_syscall_error(sync_ctx->mbox, "fstat()");
108 if (st.st_size != sync_ctx->last_stat.st_size ||
109 (sync_ctx->last_stat.st_mtime != 0 &&
110 !CMP_ST_MTIME(&st, &sync_ctx->last_stat)))
111 sync_ctx->ext_modified = TRUE;
113 sync_ctx->last_stat = st;
116 void mbox_sync_file_updated(struct mbox_sync_context *sync_ctx, bool dirty)
120 sync_ctx->last_stat.st_mtime = 0;
123 if (fstat(sync_ctx->write_fd, &sync_ctx->last_stat) < 0)
124 mbox_set_syscall_error(sync_ctx->mbox, "fstat()");
125 i_stream_sync(sync_ctx->input);
129 mbox_sync_read_next_mail(struct mbox_sync_context *sync_ctx,
135 (void)istream_raw_mbox_get_header_offset(sync_ctx->input, &offset);
136 if (istream_raw_mbox_is_eof(sync_ctx->input))
139 p_clear(sync_ctx->mail_keyword_pool);
141 mail_ctx->sync_ctx = sync_ctx;
142 mail_ctx->seq = ++sync_ctx->seq;
143 mail_ctx->header = sync_ctx->header;
146 istream_raw_mbox_get_start_offset(sync_ctx->input);
147 if (istream_raw_mbox_get_header_offset(sync_ctx->input, &mail_ctx->mail.offset) < 0) {
148 mbox_sync_set_critical(sync_ctx,
153 if (mbox_sync_parse_next_mail(sync_ctx->input, mail_ctx) < 0)
155 if (istream_raw_mbox_is_corrupted(sync_ctx->input))
158 i_assert(sync_ctx->input->v_offset != mail_ctx->mail.from_offset ||
159 sync_ctx->input->eof);
161 if (istream_raw_mbox_get_body_size(sync_ctx->input,
164 mbox_sync_set_critical(sync_ctx,
172 if (!sync_ctx->keep_recent) {
181 static void mbox_sync_read_index_syncs(struct mbox_sync_context *sync_ctx,
186 if (uid == 0 || sync_ctx->index_reset) {
191 index_sync_changes_read(sync_ctx->sync_changes, uid, sync_expunge_r,
193 if (sync_ctx->readonly) {
200 mbox_sync_read_index_rec(struct mbox_sync_context *sync_ctx,
207 if (sync_ctx->index_reset) {
213 mail_index_view_get_messages_count(sync_ctx->sync_view);
214 while (sync_ctx->idx_seq <= messages_count) {
215 rec = mail_index_lookup(sync_ctx->sync_view, sync_ctx->idx_seq);
220 mail_index_expunge(sync_ctx->t, sync_ctx->idx_seq);
221 sync_ctx->idx_seq++;
225 if (rec == NULL && uid < sync_ctx->idx_next_uid) {
227 mbox_sync_set_critical(sync_ctx,
230 uid, sync_ctx->idx_next_uid,
231 sync_ctx->seq, messages_count);
235 mbox_sync_set_critical(sync_ctx,
238 rec->uid, uid, sync_ctx->seq, messages_count);
248 static void mbox_sync_find_index_md5(struct mbox_sync_context *sync_ctx,
256 if (sync_ctx->index_reset) {
262 mail_index_view_get_messages_count(sync_ctx->sync_view);
263 while (sync_ctx->idx_seq <= messages_count) {
264 rec = mail_index_lookup(sync_ctx->sync_view, sync_ctx->idx_seq);
265 mail_index_lookup_ext(sync_ctx->sync_view,
266 sync_ctx->idx_seq,
267 sync_ctx->mbox->md5hdr_ext_idx,
273 mail_index_expunge(sync_ctx->t, sync_ctx->idx_seq);
274 sync_ctx->idx_seq++;
282 mbox_sync_update_from_offset(struct mbox_sync_context *sync_ctx,
291 mail_index_lookup_ext(sync_ctx->sync_view, sync_ctx->idx_seq,
292 sync_ctx->mbox->mbox_ext_idx,
300 mail_index_update_ext(sync_ctx->t, sync_ctx->idx_seq,
301 sync_ctx->mbox->mbox_ext_idx, &offset, NULL);
307 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
308 struct mail_index *index = sync_ctx->mbox->box.index;
315 mail_index_update_keywords(sync_ctx->t, sync_ctx->idx_seq,
323 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
326 mail_index_lookup_ext(sync_ctx->sync_view, sync_ctx->idx_seq,
327 sync_ctx->mbox->md5hdr_ext_idx, &ext_data, NULL);
330 mail_index_update_ext(sync_ctx->t, sync_ctx->idx_seq,
331 sync_ctx->mbox->md5hdr_ext_idx,
339 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
358 mail_index_lookup_keywords(sync_ctx->sync_view, sync_ctx->idx_seq,
366 sync_ctx->mail_keyword_pool,
377 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
378 struct mailbox *box = &sync_ctx->mbox->box;
399 index_sync_changes_apply(sync_ctx->sync_changes,
400 sync_ctx->mail_keyword_pool,
417 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
423 if (!sync_ctx->delay_writes) {
433 mail_index_append(sync_ctx->t, mail->uid, &sync_ctx->idx_seq);
434 mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
438 if (sync_ctx->mbox->mbox_save_md5) {
439 mail_index_update_ext(sync_ctx->t, sync_ctx->idx_seq,
440 sync_ctx->mbox->md5hdr_ext_idx,
447 mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
455 mail_index_update_flags(sync_ctx->t, sync_ctx->idx_seq,
462 mail_index_lookup_keywords(sync_ctx->sync_view,
463 sync_ctx->idx_seq, &idx_keywords);
468 if (sync_ctx->mbox->mbox_save_md5)
475 sync_ctx->last_nonrecent_uid = mail->uid;
480 if (sync_ctx->need_space_seq == 0) {
481 bool nocheck = rec == NULL || sync_ctx->expunged_space > 0;
482 mbox_sync_update_from_offset(sync_ctx, mail, nocheck);
488 struct istream *input = ctx->sync_ctx->file_input;
492 buffer_set_used_size(ctx->sync_ctx->from_line, 0);
501 buffer_append(ctx->sync_ctx->from_line, data, size);
515 static int mbox_rewrite_base_uid_last(struct mbox_sync_context *sync_ctx)
523 i_assert(sync_ctx->base_uid_last_offset != 0);
528 ret = pread_full(sync_ctx->write_fd, buf, sizeof(buf),
529 sync_ctx->base_uid_last_offset);
531 mbox_set_syscall_error(sync_ctx->mbox, "pread_full()");
535 mbox_sync_set_critical(sync_ctx,
548 if (uid_last != sync_ctx->base_uid_last) {
549 mbox_sync_set_critical(sync_ctx,
555 str = t_strdup_printf("%010u", sync_ctx->next_uid - 1);
556 if (pwrite_full(sync_ctx->write_fd, str, 10,
557 sync_ctx->base_uid_last_offset) < 0) {
558 mbox_set_syscall_error(sync_ctx->mbox, "pwrite_full()");
561 mbox_sync_file_updated(sync_ctx, FALSE);
563 sync_ctx->base_uid_last = sync_ctx->next_uid - 1;
570 string_t *str = ctx->sync_ctx->from_line;
572 if (pwrite_full(ctx->sync_ctx->write_fd, str_data(str), str_len(str),
574 mbox_set_syscall_error(ctx->sync_ctx->mbox, "pwrite_full()");
578 mbox_sync_file_updated(ctx->sync_ctx, FALSE);
582 static void update_from_offsets(struct mbox_sync_context *sync_ctx)
589 ext_idx = sync_ctx->mbox->mbox_ext_idx;
591 mails = array_get(&sync_ctx->mails, &count);
596 sync_ctx->moved_offsets = TRUE;
598 mail_index_update_ext(sync_ctx->t, mails[i].idx_seq,
605 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
606 struct mailbox *box = &sync_ctx->mbox->box;
612 mail_index_expunge(sync_ctx->t, mail_ctx->mail.idx_seq);
622 if (sync_ctx->seq == 1) {
626 if (istream_raw_mbox_has_crlf_ending(sync_ctx->input)) {
628 sync_ctx->first_mail_crlf_expunged = TRUE;
632 sync_ctx->base_uid_last_offset = 0;
635 sync_ctx->expunged_space += mail_ctx->mail.space;
640 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
645 if (sync_ctx->expunged_space > 0 && sync_ctx->need_space_seq == 0) {
647 move_diff = -sync_ctx->expunged_space;
650 if (sync_ctx->dest_first_mail) {
655 if (sync_ctx->first_mail_crlf_expunged)
681 if (sync_ctx->dest_first_mail) {
689 if (sync_ctx->delay_writes && sync_ctx->need_space_seq == 0) {
704 if (ret == 0 && sync_ctx->need_space_seq == 0) {
706 sync_ctx->need_space_seq = sync_ctx->seq;
707 sync_ctx->space_diff = 0;
709 if (sync_ctx->expunged_space > 0) {
724 sync_ctx->expunged_space;
725 mail.space = sync_ctx->expunged_space;
727 sync_ctx->space_diff = sync_ctx->expunged_space;
728 sync_ctx->expunged_space = 0;
729 i_assert(sync_ctx->space_diff < -mail_ctx->mail.space);
731 sync_ctx->need_space_seq--;
732 array_append(&sync_ctx->mails, &mail, 1);
741 struct mbox_sync_context *sync_ctx = mail_ctx->sync_ctx;
753 p_array_init(&keywords_copy, sync_ctx->saved_keywords_pool,
758 array_append(&sync_ctx->mails, &mail_ctx->mail, 1);
760 sync_ctx->space_diff += mail_ctx->mail.space;
761 if (sync_ctx->space_diff < 0) {
762 if (sync_ctx->expunged_space > 0) {
763 i_assert(sync_ctx->expunged_space ==
765 sync_ctx->expunged_space = 0;
776 i_assert(mail_ctx->mail.space >= sync_ctx->space_diff);
778 (sync_ctx->seq - sync_ctx->need_space_seq + 1);
779 needed_space = mail_ctx->mail.space - sync_ctx->space_diff;
780 if ((uoff_t)sync_ctx->space_diff > needed_space + extra_space) {
783 sync_ctx->expunged_space =
787 extra_space = sync_ctx->space_diff;
788 sync_ctx->expunged_space = 0;
790 last_seq = sync_ctx->seq - 1;
791 array_delete(&sync_ctx->mails,
792 array_count(&sync_ctx->mails) - 1, 1);
797 sync_ctx->expunged_space = 0;
798 last_seq = sync_ctx->seq;
802 extra_space = sync_ctx->space_diff;
805 mbox_sync_file_update_ext_modified(sync_ctx);
806 if (mbox_sync_rewrite(sync_ctx,
807 last_seq == sync_ctx->seq ? mail_ctx : NULL,
809 sync_ctx->need_space_seq, last_seq) < 0)
812 update_from_offsets(sync_ctx);
818 sync_ctx->need_space_seq = 0;
819 sync_ctx->space_diff = 0;
820 array_clear(&sync_ctx->mails);
821 p_clear(sync_ctx->saved_keywords_pool);
826 mbox_sync_seek_to_seq(struct mbox_sync_context *sync_ctx, uint32_t seq)
828 struct mbox_mailbox *mbox = sync_ctx->mbox;
844 old_offset = istream_raw_mbox_get_start_offset(sync_ctx->input);
846 ret = mbox_file_seek(mbox, sync_ctx->sync_view, seq, &deleted);
849 mbox_sync_set_critical(sync_ctx,
857 mbox_sync_set_critical(sync_ctx,
869 mail_index_lookup_uid(sync_ctx->sync_view, seq-1, &uid);
871 sync_ctx->prev_msg_uid = uid;
874 sync_ctx->seq = seq-1;
875 if (sync_ctx->seq == 0 &&
876 istream_raw_mbox_get_start_offset(sync_ctx->input) != 0) {
878 sync_ctx->seq++;
881 sync_ctx->idx_seq = seq;
882 sync_ctx->dest_first_mail = sync_ctx->seq == 0;
883 if (istream_raw_mbox_get_body_offset(sync_ctx->input, &offset) < 0) {
884 mbox_sync_set_critical(sync_ctx,
892 mbox_sync_seek_to_uid(struct mbox_sync_context *sync_ctx, uint32_t uid)
894 struct mail_index_view *sync_view = sync_ctx->sync_view;
899 i_assert(!sync_ctx->index_reset);
904 ret = i_stream_get_size(sync_ctx->file_input, TRUE, &size);
906 mbox_set_syscall_error(sync_ctx->mbox,
912 if (istream_raw_mbox_seek(sync_ctx->mbox->mbox_stream,
914 mbox_sync_set_critical(sync_ctx,
918 sync_ctx->idx_seq =
923 return mbox_sync_seek_to_seq(sync_ctx, seq1);
926 static int mbox_sync_partial_seek_next(struct mbox_sync_context *sync_ctx,
933 i_assert(!sync_ctx->index_reset);
937 index_sync_changes_delete_to(sync_ctx->sync_changes, next_uid);
938 if (index_sync_changes_have(sync_ctx->sync_changes))
941 if (sync_ctx->hdr->first_recent_uid <= next_uid &&
942 !sync_ctx->keep_recent) {
947 uid = index_sync_changes_get_next_uid(sync_ctx->sync_changes);
949 if (sync_ctx->hdr->first_recent_uid < sync_ctx->hdr->next_uid &&
950 (uid > sync_ctx->hdr->first_recent_uid || uid == 0) &&
951 !sync_ctx->keep_recent) {
953 uid = sync_ctx->hdr->first_recent_uid;
962 ret = mbox_sync_seek_to_uid(sync_ctx, next_uid);
966 if (sync_ctx->mbox->mbox_hdr.dirty_flag == 0)
970 mail_index_view_get_messages_count(sync_ctx->sync_view);
971 if (sync_ctx->seq + 1 != messages_count) {
972 ret = mbox_sync_seek_to_seq(sync_ctx, messages_count);
989 static void mbox_sync_hdr_update(struct mbox_sync_context *sync_ctx,
992 const struct mailbox_update *update = sync_ctx->mbox->sync_hdr_update;
995 sync_ctx->base_uid_validity = update->uid_validity;
1000 sync_ctx->base_uid_last+1 < update->min_next_uid) {
1001 i_assert(sync_ctx->next_uid <= update->min_next_uid);
1002 sync_ctx->base_uid_last = update->min_next_uid-1;
1003 sync_ctx->next_uid = update->min_next_uid;
1009 static bool mbox_sync_imapbase(struct mbox_sync_context *sync_ctx,
1012 if (sync_ctx->base_uid_validity != 0 &&
1013 sync_ctx->hdr->uid_validity != 0 &&
1014 sync_ctx->base_uid_validity != sync_ctx->hdr->uid_validity) {
1016 sync_ctx->hdr->uid_validity,
1017 sync_ctx->base_uid_validity,
1018 mailbox_get_path(&sync_ctx->mbox->box));
1019 sync_ctx->index_reset = TRUE;
1022 if (sync_ctx->mbox->sync_hdr_update != NULL)
1023 mbox_sync_hdr_update(sync_ctx, mail_ctx);
1027 static int mbox_sync_loop(struct mbox_sync_context *sync_ctx,
1038 mail_index_view_get_messages_count(sync_ctx->sync_view);
1042 ret = mbox_sync_seek_to_seq(sync_ctx, 0);
1046 if (sync_ctx->renumber_uids) {
1048 while (sync_ctx->idx_seq <= messages_count) {
1049 mail_index_expunge(sync_ctx->t,
1050 sync_ctx->idx_seq++);
1055 while ((ret = mbox_sync_read_next_mail(sync_ctx, mail_ctx)) > 0) {
1059 if (mbox_sync_imapbase(sync_ctx, mail_ctx)) {
1060 sync_ctx->mbox->mbox_hdr.dirty_flag = 1;
1068 if (sync_ctx->mbox->mbox_hdr.dirty_flag != 0)
1071 mbox_sync_set_critical(sync_ctx,
1074 sync_ctx->mbox->mbox_hdr.dirty_flag = 1;
1085 if (!mbox_sync_read_index_rec(sync_ctx, uid, &rec))
1094 (sync_ctx->delay_writes ||
1095 sync_ctx->idx_seq <= messages_count)) {
1099 sync_ctx->mbox->mbox_save_md5 = TRUE;
1101 mbox_sync_find_index_md5(sync_ctx,
1110 mbox_sync_read_index_syncs(sync_ctx,
1128 while (sync_ctx->idx_seq <= messages_count) {
1129 mail_index_expunge(sync_ctx->t,
1130 sync_ctx->idx_seq++);
1133 if (sync_ctx->next_uid == (uint32_t)-1) {
1137 mailbox_set_critical(&sync_ctx->mbox->box,
1139 sync_ctx->renumber_uids = TRUE;
1144 mail_ctx->mail.uid = sync_ctx->next_uid++;
1146 sync_ctx->prev_msg_uid = mail_ctx->mail.uid;
1149 mail_ctx->mail.idx_seq = sync_ctx->idx_seq;
1157 sync_ctx->dest_first_mail = FALSE;
1166 sync_ctx->idx_seq++;
1169 if (istream_raw_mbox_next(sync_ctx->input,
1172 offset = istream_raw_mbox_get_start_offset(sync_ctx->input);
1174 if (sync_ctx->need_space_seq != 0) {
1177 if (mbox_sync_seek(sync_ctx, offset) < 0)
1179 } else if (sync_ctx->expunged_space > 0) {
1182 mbox_sync_file_update_ext_modified(sync_ctx);
1183 if (mbox_move(sync_ctx,
1185 sync_ctx->expunged_space,
1189 if (mbox_sync_seek(sync_ctx, offset) < 0)
1193 ret = mbox_sync_partial_seek_next(sync_ctx, uid + 1,
1203 if (istream_raw_mbox_is_eof(sync_ctx->input)) {
1205 while (sync_ctx->idx_seq <= messages_count)
1206 mail_index_expunge(sync_ctx->t, sync_ctx->idx_seq++);
1210 sync_ctx->mbox->mbox_hdr.dirty_flag = 0;
1211 sync_ctx->mbox->mbox_broken_offsets = FALSE;
1213 if (uids_broken && sync_ctx->delay_writes) {
1217 sync_ctx->mbox->mbox_hdr.dirty_flag = 1;
1222 static int mbox_write_pseudo(struct mbox_sync_context *sync_ctx, bool force)
1227 i_assert(sync_ctx->write_fd != -1);
1229 if (sync_ctx->mbox->sync_hdr_update != NULL) {
1231 sync_ctx->mbox->sync_hdr_update;
1235 sync_ctx->base_uid_validity = update->uid_validity;
1239 sync_ctx->base_uid_last = update->min_next_uid-1;
1246 uid_validity = sync_ctx->base_uid_validity != 0 ?
1247 sync_ctx->base_uid_validity : sync_ctx->hdr->uid_validity;
1263 uid_validity, sync_ctx->next_uid-1);
1265 if (pwrite_full(sync_ctx->write_fd,
1268 mbox_set_syscall_error(sync_ctx->mbox,
1274 if (ftruncate(sync_ctx->write_fd, 0) < 0)
1275 mbox_set_syscall_error(sync_ctx->mbox, "ftruncate()");
1278 sync_ctx->base_uid_validity = uid_validity;
1279 sync_ctx->base_uid_last_offset = 0; /* don't bother calculating */
1280 sync_ctx->base_uid_last = sync_ctx->next_uid-1;
1284 static int mbox_append_zero(struct mbox_sync_context *sync_ctx,
1293 ret = pwrite(sync_ctx->write_fd, block,
1302 mbox_set_syscall_error(sync_ctx->mbox, "pwrite()");
1303 if (ftruncate(sync_ctx->write_fd, orig_file_size) < 0)
1304 mbox_set_syscall_error(sync_ctx->mbox, "ftruncate()");
1310 static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx,
1316 if (!istream_raw_mbox_is_eof(sync_ctx->input)) {
1317 i_assert(sync_ctx->need_space_seq == 0);
1318 i_assert(sync_ctx->expunged_space == 0);
1322 ret = i_stream_get_size(sync_ctx->file_input, TRUE, &file_size);
1324 mbox_set_syscall_error(sync_ctx->mbox, "i_stream_get_size()");
1332 if (file_size < sync_ctx->file_input->v_offset) {
1333 mbox_sync_set_critical(sync_ctx,
1336 sync_ctx->file_input->v_offset);
1339 trailer_size = file_size - sync_ctx->file_input->v_offset;
1342 if (sync_ctx->need_space_seq != 0) {
1343 i_assert(sync_ctx->write_fd != -1);
1345 i_assert(sync_ctx->space_diff < 0);
1347 (sync_ctx->seq - sync_ctx->need_space_seq + 1);
1348 sync_ctx->space_diff -= padding;
1350 i_assert(sync_ctx->expunged_space <= -sync_ctx->space_diff);
1351 sync_ctx->space_diff += sync_ctx->expunged_space;
1352 sync_ctx->expunged_space = 0;
1357 i_assert(sync_ctx->space_diff < 0);
1359 if (mbox_append_zero(sync_ctx, file_size,
1360 -sync_ctx->space_diff) < 0)
1362 mbox_sync_file_updated(sync_ctx, FALSE);
1364 if (mbox_sync_rewrite(sync_ctx, mail_ctx, file_size,
1365 -sync_ctx->space_diff, padding,
1366 sync_ctx->need_space_seq,
1367 sync_ctx->seq) < 0)
1370 update_from_offsets(sync_ctx);
1372 sync_ctx->need_space_seq = 0;
1373 array_clear(&sync_ctx->mails);
1374 p_clear(sync_ctx->saved_keywords_pool);
1377 if (sync_ctx->expunged_space > 0) {
1378 i_assert(sync_ctx->write_fd != -1);
1380 mbox_sync_file_update_ext_modified(sync_ctx);
1383 file_size = sync_ctx->last_stat.st_size;
1384 if (file_size == (uoff_t)sync_ctx->expunged_space) {
1388 } else if (sync_ctx->expunged_space == (off_t)file_size + 1 ||
1389 sync_ctx->expunged_space == (off_t)file_size + 2) {
1393 sync_ctx->expunged_space = file_size;
1396 i_assert(file_size >= sync_ctx->expunged_space + trailer_size);
1397 offset = file_size - sync_ctx->expunged_space - trailer_size;
1400 if (mbox_move(sync_ctx, offset,
1401 offset + sync_ctx->expunged_space,
1404 if (ftruncate(sync_ctx->write_fd,
1406 mbox_set_syscall_error(sync_ctx->mbox, "ftruncate()");
1411 if (mbox_write_pseudo(sync_ctx, TRUE) < 0)
1415 sync_ctx->expunged_space = 0;
1416 mbox_sync_file_updated(sync_ctx, FALSE);
1418 if (file_size == 0 && sync_ctx->mbox->sync_hdr_update != NULL) {
1419 if (mbox_write_pseudo(sync_ctx, FALSE) < 0)
1467 static int mbox_sync_update_index_header(struct mbox_sync_context *sync_ctx)
1473 if (i_stream_stat(sync_ctx->file_input, FALSE, &st) < 0) {
1474 mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()");
1478 if (sync_ctx->moved_offsets &&
1479 ((uint64_t)st->st_size == sync_ctx->mbox->mbox_hdr.sync_size ||
1480 (uint64_t)st->st_size == sync_ctx->orig_size)) {
1493 while (sync_ctx->orig_mtime == st->st_mtime) {
1495 if (utime(mailbox_get_path(&sync_ctx->mbox->box), NULL) < 0) {
1496 mbox_set_syscall_error(sync_ctx->mbox,
1501 if (i_stream_stat(sync_ctx->file_input, FALSE, &st) < 0) {
1502 mbox_set_syscall_error(sync_ctx->mbox,
1509 sync_ctx->mbox->mbox_hdr.sync_mtime = st->st_mtime;
1510 sync_ctx->mbox->mbox_hdr.sync_size = st->st_size;
1511 mbox_sync_index_update_ext_header(sync_ctx->mbox, sync_ctx->t);
1515 i_assert(sync_ctx->base_uid_validity != 0 || st->st_size <= 0);
1517 if (sync_ctx->base_uid_validity == 0) {
1518 sync_ctx->base_uid_validity = sync_ctx->hdr->uid_validity != 0 ?
1519 sync_ctx->hdr->uid_validity :
1520 mbox_get_uidvalidity_next(sync_ctx->mbox->box.list);
1522 if (sync_ctx->base_uid_validity != sync_ctx->hdr->uid_validity) {
1523 mail_index_update_header(sync_ctx->t,
1525 &sync_ctx->base_uid_validity,
1526 sizeof(sync_ctx->base_uid_validity), TRUE);
1529 if (istream_raw_mbox_is_eof(sync_ctx->input) &&
1530 sync_ctx->next_uid != sync_ctx->hdr->next_uid) {
1531 i_assert(sync_ctx->next_uid != 0);
1532 mail_index_update_header(sync_ctx->t,
1534 &sync_ctx->next_uid, sizeof(sync_ctx->next_uid), FALSE);
1537 if (sync_ctx->last_nonrecent_uid < sync_ctx->hdr->first_recent_uid) {
1540 sync_ctx->last_nonrecent_uid =
1541 sync_ctx->hdr->first_recent_uid - 1;
1545 view = mail_index_transaction_open_updated_view(sync_ctx->t);
1546 if (mail_index_lookup_seq_range(view, sync_ctx->last_nonrecent_uid + 1,
1548 mailbox_recent_flags_set_seqs(&sync_ctx->mbox->box,
1553 first_recent_uid = !sync_ctx->keep_recent ?
1554 sync_ctx->next_uid : sync_ctx->last_nonrecent_uid + 1;
1555 if (sync_ctx->hdr->first_recent_uid < first_recent_uid) {
1556 mail_index_update_header(sync_ctx->t,
1563 static void mbox_sync_restart(struct mbox_sync_context *sync_ctx)
1565 sync_ctx->base_uid_validity = 0;
1566 sync_ctx->base_uid_last = 0;
1567 sync_ctx->base_uid_last_offset = 0;
1569 array_clear(&sync_ctx->mails);
1570 p_clear(sync_ctx->saved_keywords_pool);
1572 index_sync_changes_reset(sync_ctx->sync_changes);
1573 mail_index_sync_reset(sync_ctx->index_sync_ctx);
1574 mail_index_transaction_reset(sync_ctx->t);
1576 if (sync_ctx->index_reset) {
1577 mail_index_reset(sync_ctx->t);
1578 sync_ctx->reset_hdr.next_uid = 1;
1579 sync_ctx->hdr = &sync_ctx->reset_hdr;
1580 mailbox_recent_flags_reset(&sync_ctx->mbox->box);
1583 sync_ctx->prev_msg_uid = 0;
1584 sync_ctx->next_uid = sync_ctx->hdr->next_uid;
1585 sync_ctx->idx_next_uid = sync_ctx->hdr->next_uid;
1586 sync_ctx->seq = 0;
1587 sync_ctx->idx_seq = 1;
1588 sync_ctx->need_space_seq = 0;
1589 sync_ctx->expunged_space = 0;
1590 sync_ctx->space_diff = 0;
1592 sync_ctx->dest_first_mail = TRUE;
1593 sync_ctx->ext_modified = FALSE;
1594 sync_ctx->errors = FALSE;
1597 static int mbox_sync_do(struct mbox_sync_context *sync_ctx,
1600 struct mbox_index_header *mbox_hdr = &sync_ctx->mbox->mbox_hdr;
1607 if (i_stream_stat(sync_ctx->file_input, FALSE, &st) < 0) {
1608 mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()");
1611 sync_ctx->last_stat = *st;
1612 sync_ctx->orig_size = st->st_size;
1613 sync_ctx->orig_atime = st->st_atime;
1614 sync_ctx->orig_mtime = st->st_mtime;
1634 sync_ctx->mbox->mbox_hdr.dirty_flag = 1;
1640 sync_ctx->mbox->mbox_hdr.dirty_flag = 1;
1643 mbox_sync_restart(sync_ctx);
1645 ret = mbox_sync_loop(sync_ctx, &mail_ctx, partial);
1646 if (ret > 0 && !sync_ctx->errors)
1654 if (sync_ctx->delay_writes &&
1655 (sync_ctx->errors || sync_ctx->renumber_uids)) {
1658 if (!sync_ctx->readonly)
1659 sync_ctx->delay_writes = FALSE;
1664 mbox_sync_restart(sync_ctx);
1668 if (mbox_sync_handle_eof_updates(sync_ctx, &mail_ctx) < 0)
1674 index_sync_changes_reset(sync_ctx->sync_changes);
1676 if (sync_ctx->base_uid_last != sync_ctx->next_uid-1 &&
1677 ret > 0 && !sync_ctx->delay_writes &&
1678 sync_ctx->base_uid_last_offset != 0) {
1681 ret = mbox_rewrite_base_uid_last(sync_ctx);
1686 if (mbox_sync_update_index_header(sync_ctx) < 0)
1782 static void mbox_sync_context_free(struct mbox_sync_context *sync_ctx)
1784 index_sync_changes_deinit(&sync_ctx->sync_changes);
1785 index_storage_expunging_deinit(&sync_ctx->mbox->box);
1786 if (sync_ctx->index_sync_ctx != NULL)
1787 mail_index_sync_rollback(&sync_ctx->index_sync_ctx);
1788 pool_unref(&sync_ctx->mail_keyword_pool);
1789 pool_unref(&sync_ctx->saved_keywords_pool);
1790 str_free(&sync_ctx->header);
1791 str_free(&sync_ctx->from_line);
1792 array_free(&sync_ctx->mails);
1801 struct mbox_sync_context sync_ctx;
1882 sync_ctx.hdr = mail_index_get_header(sync_view);
1883 if (sync_ctx.hdr->first_recent_uid < sync_ctx.hdr->next_uid)
1900 i_zero(&sync_ctx);
1901 sync_ctx.mbox = mbox;
1902 sync_ctx.keep_recent =
1905 sync_ctx.hdr = mail_index_get_header(sync_view);
1906 sync_ctx.from_line = str_new(default_pool, 256);
1907 sync_ctx.header = str_new(default_pool, 4096);
1909 sync_ctx.index_sync_ctx = index_sync_ctx;
1910 sync_ctx.sync_view = sync_view;
1911 sync_ctx.t = trans;
1912 sync_ctx.mail_keyword_pool =
1914 sync_ctx.saved_keywords_pool =
1920 i_array_init(&sync_ctx.mails, 64);
1922 sync_ctx.flags = flags;
1923 sync_ctx.readonly = readonly;
1924 sync_ctx.delay_writes = delay_writes;
1926 sync_ctx.sync_changes =
1928 sync_ctx.delay_writes);
1936 mbox_sync_read_index_syncs(&sync_ctx, 1, &expunged);
1938 index_sync_changes_get_next_uid(sync_ctx.sync_changes);
1940 sync_ctx.index_sync_ctx = NULL;
1941 mbox_sync_context_free(&sync_ctx);
1949 mbox_sync_context_free(&sync_ctx);
1955 mbox_sync_context_free(&sync_ctx);
1959 sync_ctx.file_input = sync_ctx.mbox->mbox_file_stream;
1960 sync_ctx.input = sync_ctx.mbox->mbox_stream;
1961 sync_ctx.write_fd = sync_ctx.mbox->mbox_lock_type != F_WRLCK ? -1 :
1962 sync_ctx.mbox->mbox_fd;
1964 ret = mbox_sync_do(&sync_ctx, flags);
1972 sync_ctx.t = NULL;
1973 sync_ctx.index_sync_ctx = NULL;
1975 if (ret == 0 && mbox->mbox_fd != -1 && sync_ctx.keep_recent &&
1987 buf.actime = sync_ctx.orig_atime;
2004 mbox_sync_context_free(&sync_ctx);