Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/imap/imap-sync.c @ 6355:08ee6385e7a9 HEAD
Fixed infinite loop if a transaction was seen for messages that weren't
visible in this session yet.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 08 Sep 2007 03:29:08 +0300 |
parents | f52e7d1402b5 |
children | 65c69a53a7be |
rev | line source |
---|---|
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
1 /* Copyright (C) 2002-2004 Timo Sirainen */ |
2322 | 2 |
3 #include "common.h" | |
4 #include "str.h" | |
3016
61c8d205d887
Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents:
2884
diff
changeset
|
5 #include "mail-storage.h" |
2322 | 6 #include "imap-util.h" |
7 #include "imap-sync.h" | |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
8 #include "commands.h" |
2322 | 9 |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
10 struct cmd_sync_context { |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
11 const char *tagline; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
12 struct imap_sync_context *sync_ctx; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
13 }; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
14 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
15 struct imap_sync_context { |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
16 struct client *client; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
17 struct mailbox *box; |
3765
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
18 enum imap_sync_flags imap_flags; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
19 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
20 struct mailbox_transaction_context *t; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
21 struct mailbox_sync_context *sync_ctx; |
3209
923ff19873d4
Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents:
3204
diff
changeset
|
22 struct mail *mail; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
23 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
24 struct mailbox_sync_rec sync_rec; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
25 uint32_t seq; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
26 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
27 unsigned int messages_count; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
28 |
5762
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
29 unsigned int failed:1; |
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
30 unsigned int no_newmail:1; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
31 }; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
32 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
33 struct imap_sync_context * |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
34 imap_sync_init(struct client *client, struct mailbox *box, |
3765
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
35 enum imap_sync_flags imap_flags, enum mailbox_sync_flags flags) |
2322 | 36 { |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
37 struct imap_sync_context *ctx; |
3515
1c9f3264f2fc
Send untagged FLAGS / PERMANENTFLAGS replies if keywords list changed.
Timo Sirainen <tss@iki.fi>
parents:
3358
diff
changeset
|
38 struct mailbox_status status; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
39 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
40 i_assert(client->mailbox == box); |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
41 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
42 ctx = i_new(struct imap_sync_context, 1); |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
43 ctx->client = client; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
44 ctx->box = box; |
3765
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
45 ctx->imap_flags = imap_flags; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
46 |
2884
173a0296e81d
Update view's header only after syncing the view. This and other changes fix
Timo Sirainen <tss@iki.fi>
parents:
2518
diff
changeset
|
47 ctx->sync_ctx = mailbox_sync_init(box, flags); |
3209
923ff19873d4
Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents:
3204
diff
changeset
|
48 ctx->t = mailbox_transaction_begin(box, 0); |
923ff19873d4
Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents:
3204
diff
changeset
|
49 ctx->mail = mail_alloc(ctx->t, MAIL_FETCH_FLAGS, 0); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
50 ctx->messages_count = client->messages_count; |
3515
1c9f3264f2fc
Send untagged FLAGS / PERMANENTFLAGS replies if keywords list changed.
Timo Sirainen <tss@iki.fi>
parents:
3358
diff
changeset
|
51 |
1c9f3264f2fc
Send untagged FLAGS / PERMANENTFLAGS replies if keywords list changed.
Timo Sirainen <tss@iki.fi>
parents:
3358
diff
changeset
|
52 /* if keyword list changed, send the new list before flag changes */ |
6275
913b188f4dd4
Removed explicit locking from views and maps. They were already locked all
Timo Sirainen <tss@iki.fi>
parents:
5916
diff
changeset
|
53 mailbox_get_status(ctx->box, STATUS_KEYWORDS, &status); |
913b188f4dd4
Removed explicit locking from views and maps. They were already locked all
Timo Sirainen <tss@iki.fi>
parents:
5916
diff
changeset
|
54 if (client_save_keywords(&client->keywords, status.keywords)) |
913b188f4dd4
Removed explicit locking from views and maps. They were already locked all
Timo Sirainen <tss@iki.fi>
parents:
5916
diff
changeset
|
55 client_send_mailbox_flags(client, box, status.keywords); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
56 return ctx; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
57 } |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
58 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
59 int imap_sync_deinit(struct imap_sync_context *ctx) |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
60 { |
2322 | 61 struct mailbox_status status; |
5089 | 62 int ret; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
63 |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
64 mail_free(&ctx->mail); |
3209
923ff19873d4
Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents:
3204
diff
changeset
|
65 |
5848
064aa8ff69c2
Disconnect client if UIDVALIDITY changes.
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
66 if (mailbox_sync_deinit(&ctx->sync_ctx, STATUS_UIDVALIDITY | |
4848
967de900c73a
Mailbox list indexing and related changes. Currently works only with
Timo Sirainen <tss@iki.fi>
parents:
4038
diff
changeset
|
67 STATUS_MESSAGES | STATUS_RECENT, &status) < 0 || |
967de900c73a
Mailbox list indexing and related changes. Currently works only with
Timo Sirainen <tss@iki.fi>
parents:
4038
diff
changeset
|
68 ctx->failed) { |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
69 mailbox_transaction_rollback(&ctx->t); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
70 i_free(ctx); |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
71 return -1; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
72 } |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
73 |
5089 | 74 ret = mailbox_transaction_commit(&ctx->t, 0); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
75 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
76 t_push(); |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
77 |
5848
064aa8ff69c2
Disconnect client if UIDVALIDITY changes.
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
78 if (status.uidvalidity != ctx->client->uidvalidity) { |
064aa8ff69c2
Disconnect client if UIDVALIDITY changes.
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
79 /* most clients would get confused by this. disconnect them. */ |
064aa8ff69c2
Disconnect client if UIDVALIDITY changes.
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
80 client_disconnect_with_error(ctx->client, |
064aa8ff69c2
Disconnect client if UIDVALIDITY changes.
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
81 "Mailbox UIDVALIDITY changed"); |
064aa8ff69c2
Disconnect client if UIDVALIDITY changes.
Timo Sirainen <tss@iki.fi>
parents:
5812
diff
changeset
|
82 } |
5765 | 83 if (!ctx->no_newmail) { |
5916 | 84 if (status.messages < ctx->messages_count) |
85 i_panic("Message count decreased"); | |
5762
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
86 ctx->client->messages_count = status.messages; |
5765 | 87 if (status.messages != ctx->messages_count) { |
88 client_send_line(ctx->client, | |
89 t_strdup_printf("* %u EXISTS", status.messages)); | |
90 } | |
91 if (status.recent != ctx->client->recent_count && !ctx->no_newmail) { | |
92 ctx->client->recent_count = status.recent; | |
93 client_send_line(ctx->client, | |
94 t_strdup_printf("* %u RECENT", status.recent)); | |
95 } | |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
96 } |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
97 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
98 t_pop(); |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
99 i_free(ctx); |
5089 | 100 return ret; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
101 } |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
102 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
103 int imap_sync_more(struct imap_sync_context *ctx) |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
104 { |
3016
61c8d205d887
Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents:
2884
diff
changeset
|
105 enum mail_flags flags; |
61c8d205d887
Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents:
2884
diff
changeset
|
106 const char *const *keywords; |
2322 | 107 string_t *str; |
3107
adb1a574215b
FETCH deinitialization wasn't done properly
Timo Sirainen <tss@iki.fi>
parents:
3016
diff
changeset
|
108 int ret = 1; |
2322 | 109 |
110 t_push(); | |
111 str = t_str_new(256); | |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
112 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
113 for (;;) { |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
114 if (ctx->seq == 0) { |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
115 /* get next one */ |
6279
f52e7d1402b5
mail_index_view_sync_next() and mailbox_sync_next() returns now bool.
Timo Sirainen <tss@iki.fi>
parents:
6277
diff
changeset
|
116 if (!mailbox_sync_next(ctx->sync_ctx, &ctx->sync_rec)) { |
f52e7d1402b5
mail_index_view_sync_next() and mailbox_sync_next() returns now bool.
Timo Sirainen <tss@iki.fi>
parents:
6277
diff
changeset
|
117 /* finished */ |
f52e7d1402b5
mail_index_view_sync_next() and mailbox_sync_next() returns now bool.
Timo Sirainen <tss@iki.fi>
parents:
6277
diff
changeset
|
118 ret = 1; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
119 break; |
3107
adb1a574215b
FETCH deinitialization wasn't done properly
Timo Sirainen <tss@iki.fi>
parents:
3016
diff
changeset
|
120 } |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
121 } |
2322 | 122 |
4008
4e1a816a82a1
Don't notify client about changes in messages it hasn't yet even been
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
123 if (ctx->sync_rec.seq2 > ctx->messages_count) { |
4e1a816a82a1
Don't notify client about changes in messages it hasn't yet even been
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
124 /* don't send change notifications of messages we |
4e1a816a82a1
Don't notify client about changes in messages it hasn't yet even been
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
125 haven't even announced to client yet */ |
6355
08ee6385e7a9
Fixed infinite loop if a transaction was seen for messages that weren't
Timo Sirainen <tss@iki.fi>
parents:
6279
diff
changeset
|
126 if (ctx->sync_rec.seq1 > ctx->messages_count) { |
08ee6385e7a9
Fixed infinite loop if a transaction was seen for messages that weren't
Timo Sirainen <tss@iki.fi>
parents:
6279
diff
changeset
|
127 ctx->seq = 0; |
4008
4e1a816a82a1
Don't notify client about changes in messages it hasn't yet even been
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
128 continue; |
6355
08ee6385e7a9
Fixed infinite loop if a transaction was seen for messages that weren't
Timo Sirainen <tss@iki.fi>
parents:
6279
diff
changeset
|
129 } |
4008
4e1a816a82a1
Don't notify client about changes in messages it hasn't yet even been
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
130 ctx->sync_rec.seq2 = ctx->messages_count; |
4e1a816a82a1
Don't notify client about changes in messages it hasn't yet even been
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
131 } |
4e1a816a82a1
Don't notify client about changes in messages it hasn't yet even been
Timo Sirainen <tss@iki.fi>
parents:
3963
diff
changeset
|
132 |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
133 switch (ctx->sync_rec.type) { |
2322 | 134 case MAILBOX_SYNC_TYPE_FLAGS: |
3016
61c8d205d887
Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents:
2884
diff
changeset
|
135 case MAILBOX_SYNC_TYPE_KEYWORDS: |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
136 if (ctx->seq == 0) |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
137 ctx->seq = ctx->sync_rec.seq1; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
138 |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
139 ret = 1; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
140 for (; ctx->seq <= ctx->sync_rec.seq2; ctx->seq++) { |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
141 if (ret <= 0) |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
142 break; |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
143 |
6277
5f66277bbe40
mail_index_lookup*() can't fail anymore. Changed several APIs not to return
Timo Sirainen <tss@iki.fi>
parents:
6275
diff
changeset
|
144 mail_set_seq(ctx->mail, ctx->seq); |
3209
923ff19873d4
Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents:
3204
diff
changeset
|
145 flags = mail_get_flags(ctx->mail); |
923ff19873d4
Major mail-storage API changes. It's now a bit cleaner and much more plugin
Timo Sirainen <tss@iki.fi>
parents:
3204
diff
changeset
|
146 keywords = mail_get_keywords(ctx->mail); |
2322 | 147 |
148 str_truncate(str, 0); | |
3765
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
149 str_printfa(str, "* %u FETCH (", ctx->seq); |
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
150 if (ctx->imap_flags & IMAP_SYNC_FLAG_SEND_UID) { |
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
151 str_printfa(str, "UID %u ", |
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
152 ctx->mail->uid); |
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
153 } |
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
154 str_append(str, "FLAGS ("); |
3016
61c8d205d887
Initial support for keywords. Syncing to mbox/maildir doesn't work yet.
Timo Sirainen <tss@iki.fi>
parents:
2884
diff
changeset
|
155 imap_write_flags(str, flags, keywords); |
2322 | 156 str_append(str, "))"); |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
157 |
3107
adb1a574215b
FETCH deinitialization wasn't done properly
Timo Sirainen <tss@iki.fi>
parents:
3016
diff
changeset
|
158 ret = client_send_line(ctx->client, str_c(str)); |
2322 | 159 } |
160 break; | |
161 case MAILBOX_SYNC_TYPE_EXPUNGE: | |
4038
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
162 if (ctx->seq == 0) |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
163 ctx->seq = ctx->sync_rec.seq2; |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
164 ret = 1; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
165 for (; ctx->seq >= ctx->sync_rec.seq1; ctx->seq--) { |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
166 if (ret <= 0) |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
167 break; |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
168 |
2322 | 169 str_truncate(str, 0); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
170 str_printfa(str, "* %u EXPUNGE", ctx->seq); |
3107
adb1a574215b
FETCH deinitialization wasn't done properly
Timo Sirainen <tss@iki.fi>
parents:
3016
diff
changeset
|
171 ret = client_send_line(ctx->client, str_c(str)); |
2322 | 172 } |
4038
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
173 if (ctx->seq < ctx->sync_rec.seq1) { |
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
174 /* update only after we're finished, so that |
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
175 the seq2 > messages_count check above |
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
176 doesn't break */ |
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
177 ctx->messages_count -= |
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
178 ctx->sync_rec.seq2 - |
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
179 ctx->sync_rec.seq1 + 1; |
6d80874fd704
Update message_count only after expunge sends are finished or we'll get to
Timo Sirainen <tss@iki.fi>
parents:
4008
diff
changeset
|
180 } |
2322 | 181 break; |
182 } | |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
183 if (ret <= 0) { |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
184 /* failure / buffer full */ |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
185 break; |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
186 } |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
187 |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
188 ctx->seq = 0; |
2322 | 189 } |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
190 t_pop(); |
3107
adb1a574215b
FETCH deinitialization wasn't done properly
Timo Sirainen <tss@iki.fi>
parents:
3016
diff
changeset
|
191 return ret; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
192 } |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
193 |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
194 int imap_sync_nonselected(struct mailbox *box, enum mailbox_sync_flags flags) |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
195 { |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
196 struct mailbox_sync_context *ctx; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
197 struct mailbox_sync_rec sync_rec; |
2322 | 198 |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
199 ctx = mailbox_sync_init(box, flags); |
6279
f52e7d1402b5
mail_index_view_sync_next() and mailbox_sync_next() returns now bool.
Timo Sirainen <tss@iki.fi>
parents:
6277
diff
changeset
|
200 while (mailbox_sync_next(ctx, &sync_rec)) |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
201 ; |
4848
967de900c73a
Mailbox list indexing and related changes. Currently works only with
Timo Sirainen <tss@iki.fi>
parents:
4038
diff
changeset
|
202 return mailbox_sync_deinit(&ctx, 0, NULL); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
203 } |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
204 |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3765
diff
changeset
|
205 static bool cmd_sync_continue(struct client_command_context *cmd) |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
206 { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
207 struct cmd_sync_context *ctx = cmd->context; |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
208 int ret; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
209 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
210 if (cmd->cancel) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
211 ret = 0; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
212 else { |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
213 if ((ret = imap_sync_more(ctx->sync_ctx)) == 0) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
214 return FALSE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
215 } |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
216 |
3652
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
217 if (ret < 0) |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
218 ctx->sync_ctx->failed = TRUE; |
440137d72ca0
When output buffer got full while sending syncing changes, we sent the last
Timo Sirainen <tss@iki.fi>
parents:
3515
diff
changeset
|
219 |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5765
diff
changeset
|
220 cmd->client->syncing = FALSE; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
221 if (imap_sync_deinit(ctx->sync_ctx) < 0) { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
222 client_send_untagged_storage_error(cmd->client, |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
223 mailbox_get_storage(cmd->client->mailbox)); |
2322 | 224 } |
225 | |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
226 if (!cmd->cancel) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
227 client_send_tagline(cmd, ctx->tagline); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
228 return TRUE; |
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
229 } |
2322 | 230 |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3765
diff
changeset
|
231 bool cmd_sync(struct client_command_context *cmd, enum mailbox_sync_flags flags, |
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3765
diff
changeset
|
232 enum imap_sync_flags imap_flags, const char *tagline) |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
233 { |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
234 struct client *client = cmd->client; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
235 struct cmd_sync_context *ctx; |
5762
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
236 bool no_newmail; |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
237 |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
238 i_assert(client->output_lock == cmd || client->output_lock == NULL); |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
239 |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
240 if (client->mailbox == NULL || |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
241 mailbox_transaction_get_count(client->mailbox) > 0) { |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
242 client_send_tagline(cmd, tagline); |
2427
e1616067df5c
Syncing works now too without buffering everything. Also fixed handling
Timo Sirainen <tss@iki.fi>
parents:
2332
diff
changeset
|
243 return TRUE; |
2322 | 244 } |
245 | |
5762
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
246 no_newmail = (client_workarounds & WORKAROUND_DELAY_NEWMAIL) != 0 && |
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
247 (flags & MAILBOX_SYNC_FLAG_FAST) != 0; |
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
248 if (no_newmail) { |
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
249 /* expunges might break the client just as badly as new mail |
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
250 notifications. */ |
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
251 flags |= MAILBOX_SYNC_FLAG_NO_EXPUNGES; |
3358
d6723f532d26
Removed SYNC_FAST_FLAG from EXPUNGE command. Changed delay-newmail
Timo Sirainen <tss@iki.fi>
parents:
3209
diff
changeset
|
252 } |
3204
c8fffa286b6a
Renamed oe6-fetch-no-newmail workaround to delay-newmail and changed it to
Timo Sirainen <tss@iki.fi>
parents:
3141
diff
changeset
|
253 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
254 ctx = p_new(cmd->pool, struct cmd_sync_context, 1); |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
255 ctx->tagline = p_strdup(cmd->pool, tagline); |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
256 ctx->sync_ctx = imap_sync_init(client, client->mailbox, |
3765
ce76b6b8ff11
UID STORE command must return UID parameter in FETCH replies.
Timo Sirainen <tss@iki.fi>
parents:
3652
diff
changeset
|
257 imap_flags, flags); |
5762
9e762641180d
Handle delay-newmail workaround completely in the IMAP code.
Timo Sirainen <tss@iki.fi>
parents:
5089
diff
changeset
|
258 ctx->sync_ctx->no_newmail = no_newmail; |
2322 | 259 |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
260 cmd->func = cmd_sync_continue; |
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
261 cmd->context = ctx; |
4939
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
262 cmd->output_pending = TRUE; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
263 if (client->input_lock == cmd) |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
264 client->input_lock = NULL; |
ff2272c228cc
Dovecot is now able to execute multiple commands at the same time.
Timo Sirainen <tss@iki.fi>
parents:
4848
diff
changeset
|
265 client->output_lock = NULL; |
5812
71176467310e
Fixes to handling command ambiguity. Don't allow any commands that handle
Timo Sirainen <tss@iki.fi>
parents:
5765
diff
changeset
|
266 client->syncing = TRUE; |
3141
61abed5f7864
Moved command-specific variables from struct client to struct
Timo Sirainen <tss@iki.fi>
parents:
3107
diff
changeset
|
267 return cmd_sync_continue(cmd); |
2322 | 268 } |