mbox-sync-update.c revision bb10ebcf076c959c752f583746d83805d7686df8
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (C) 2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void status_flags_append(struct mbox_sync_mail_context *ctx,
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen /* kludgy kludgy */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mbox_sync_move_buffer(struct mbox_sync_mail_context *ctx,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* FIXME: if (diff < ctx->space && pos < ctx->offset) then
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen move the data only up to space offset and give/take the
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen space from there. update header_last_change accordingly.
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen (except pos and offset can't be compared directly) */
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen for (i = 0; i < MBOX_HDR_COUNT; i++) {
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainenstatic void status_flags_replace(struct mbox_sync_mail_context *ctx, size_t pos,
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen unsigned char *data;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* how many bytes do we need? */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen for (i = 0, need = 0; flags_list[i].chr != 0; i++) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if ((ctx->mail.flags & flags_list[i].flag) != 0)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* how many bytes do we have now? */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen data = buffer_get_modifyable_data(ctx->header, &size);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen /* see if this is unknown flag for us */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* save this one */
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 Sirainenstatic void keywords_append(struct mbox_sync_context *sync_ctx, string_t *dest,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ARRAY_SET_TYPE(keyword_indexes_arr, unsigned int);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const char *const *keyword_names;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen const unsigned int *keyword_indexes;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen keyword_names = array_get(sync_ctx->ibox->keyword_names,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen keyword_indexes = array_get(keyword_indexes_arr, &idx_count);
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen for (i = 0, last_break = 0; i < idx_count; i++) {
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen i_assert(keyword_indexes[i] < keywords_count);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* try avoid overly long lines but cutting them
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen every 70 chars or so */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen str_append(dest, keyword_names[keyword_indexes[i]]);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenkeywords_append_all(struct mbox_sync_mail_context *ctx, string_t *dest)
197ad81605dc0f6d2ebc9ad99994db5ca6d76699Timo Sirainen const char *const *names;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen const unsigned char *p;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen unsigned int i, count;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* set last_break to beginning of line */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen for (last_break = str_len(dest); last_break > 0; last_break--) {
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen names = array_get(ctx->sync_ctx->ibox->keyword_names, &count);
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen for (i = 0; i < count; i++) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* try avoid overly long lines but cutting them
d22301419109ed4a38351715e6760011421dadecTimo Sirainen every 70 chars or so */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic void mbox_sync_add_missing_headers(struct mbox_sync_mail_context *ctx)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen old_hdr_size = ctx->body_offset - ctx->hdr_offset;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen str_data(ctx->header)[new_hdr_size-1] != '\n') {
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen /* broken header - doesn't end with \n. fix it. */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] = str_len(ctx->header);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_UID] == (size_t)-1 && !ctx->pseudo) {
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_UID] = str_len(ctx->header);
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen str_printfa(ctx->header, "%u\n", ctx->mail.uid);
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_STATUS] == (size_t)-1 &&
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen ctx->hdr_pos[MBOX_HDR_STATUS] = str_len(ctx->header);
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_STATUS] == (size_t)-1 &&
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen (ctx->mail.flags & XSTATUS_FLAGS_MASK) != 0) {
58eb2cb24dbeadd94500670acad7ceb1c8b0d9b4Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_STATUS] = str_len(ctx->header);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] == (size_t)-1 &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] = str_len(ctx->header);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen ctx->mail.body_size >= MBOX_MIN_CONTENT_LENGTH_SIZE) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen str_printfa(ctx->header, "Content-Length: %"PRIuUOFF_T"\n",
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainenstatic void mbox_sync_update_status(struct mbox_sync_mail_context *ctx)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (ctx->hdr_pos[MBOX_HDR_STATUS] != (size_t)-1) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen status_flags_replace(ctx, ctx->hdr_pos[MBOX_HDR_STATUS],
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstatic void mbox_sync_update_xstatus(struct mbox_sync_mail_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_STATUS] != (size_t)-1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen status_flags_replace(ctx, ctx->hdr_pos[MBOX_HDR_X_STATUS],
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void mbox_sync_update_line(struct mbox_sync_mail_context *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *hdr, *p;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* shouldn't really happen, but allow anyway.. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->mail.space > 0 && ctx->mail.offset >= file_pos &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* extra space points to this line. remove it. */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mbox_sync_move_buffer(ctx, pos, str_len(new_line), p - hdr + 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_copy(ctx->header, pos, new_line, 0, (size_t)-1);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenstatic void mbox_sync_update_xkeywords(struct mbox_sync_mail_context *ctx)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_KEYWORDS] == (size_t)-1)
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen keywords_append(ctx->sync_ctx, str, &ctx->mail.keywords);
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_KEYWORDS], str);
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainenstatic void mbox_sync_update_x_imap_base(struct mbox_sync_mail_context *ctx)
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen struct mbox_sync_context *sync_ctx = ctx->sync_ctx;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ctx->hdr_pos[MBOX_HDR_X_IMAPBASE] == (size_t)-1)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (sync_ctx->update_base_uid_last <= sync_ctx->base_uid_last)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* see if anything changed */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* update uid-last field in X-IMAPbase */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen str_printfa(str, "%u %010u", sync_ctx->base_uid_validity,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen sync_ctx->update_base_uid_last : sync_ctx->base_uid_last);
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_IMAPBASE], str);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenstatic void mbox_sync_update_x_uid(struct mbox_sync_mail_context *ctx)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (ctx->hdr_pos[MBOX_HDR_X_UID] == (size_t)-1 ||
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mbox_sync_update_line(ctx, ctx->hdr_pos[MBOX_HDR_X_UID], str);
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainenvoid mbox_sync_update_header(struct mbox_sync_mail_context *ctx)
58eb2cb24dbeadd94500670acad7ceb1c8b0d9b4Timo Sirainen mbox_sync_apply_index_syncs(ctx->sync_ctx, &ctx->mail,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mbox_sync_update_header_from(struct mbox_sync_mail_context *ctx,
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen ctx->mail.flags = (ctx->mail.flags & ~STATUS_FLAGS_MASK) |
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen ctx->mail.flags = (ctx->mail.flags & ~XSTATUS_FLAGS_MASK) |
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen /* no keywords for this mail */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen } else if (!array_is_created(&ctx->mail.keywords)) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* adding first keywords */
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen unsigned int,
d0d7fcf3ce44f26fdf34c1542a25cec644c5c4c7Timo Sirainen } else if (!buffer_cmp(ctx->mail.keywords.buffer,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* keywords changed. */