maildir-mail.c revision 2526d52441ef368215ab6bf04fd0356d3b09d235
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen/* Copyright (C) 2003 Timo Sirainen */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainendo_open(struct maildir_mailbox *mbox, const char *path, int *fd)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainendo_stat(struct maildir_mailbox *mbox, const char *path, struct stat *st)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic struct istream *
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenmaildir_open_mail(struct maildir_mailbox *mbox, struct mail *mail,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (maildir_file_do(mbox, mail->uid, do_open, &fd) < 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen return i_stream_create_fd(fd, MAIL_READ_BLOCK_SIZE, TRUE);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic int maildir_mail_stat(struct mail *mail, struct stat *st)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->box;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct index_mail_data *data = &((struct index_mail *)mail)->data;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (data->access_part != 0 && data->stream == NULL) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* we're going to open the mail anyway */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_storage_set_critical(&mbox->storage->storage,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen "fstat(maildir) failed: %m");
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (maildir_file_do(mbox, mail->uid, do_stat, st) <= 0)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen path = maildir_save_file_get_path(mail->transaction, mail->seq);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic time_t maildir_mail_get_received_date(struct mail *_mail)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen index_mail_cache_add(mail, MAIL_CACHE_RECEIVED_DATE, &t, sizeof(t));
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic time_t maildir_mail_get_save_date(struct mail *_mail)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t));
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenmaildir_mail_get_fname(struct maildir_mailbox *mbox, struct mail *mail,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen const char **fname_r)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen *fname_r = maildir_uidlist_lookup(mbox->uidlist, mail->uid, &flags);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic int maildir_get_pop3_state(struct index_mail *mail)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* if this mail itself has non-pop3 fields we know we're not
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen allowed_pop3_fields = MAIL_FETCH_FLAGS | MAIL_FETCH_STREAM_HEADER |
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen MAIL_FETCH_STREAM_BODY | MAIL_FETCH_UIDL_FILE_NAME |
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen (mail->wanted_fields & allowed_pop3_fields) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* get vsize decision */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen vsize_idx = mail->ibox->cache_fields[MAIL_CACHE_VIRTUAL_FULL_SIZE].idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen vsize_dec = mail_cache_field_get_decision(mail->ibox->cache,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* also check if there are any non-vsize cached fields */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen fields = mail_cache_register_get_list(mail->ibox->cache,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < count; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dec = fields[i].decision & ~MAIL_CACHE_DECISION_FORCED;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* either nothing is cached, or only vsize is cached. */
d4dcb9c30dba354cff7af6d303ecef7698194c55Timo Sirainen } else if (vsize_dec != MAIL_CACHE_DECISION_YES) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* if virtual size isn't cached permanently,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen POP3 isn't being used */
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen /* possibly a mixed pop3/imap */
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainenstatic uoff_t maildir_mail_get_virtual_size(struct mail *_mail)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (index_mail_get_cached_virtual_size(mail) != (uoff_t)-1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!maildir_mail_get_fname(mbox, _mail, &fname))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen path = maildir_save_file_get_path(_mail->transaction,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* size can be included in filename */
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen if (maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE,
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen /* size can be included in uidlist entry */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen value = maildir_uidlist_lookup_ext(mbox->uidlist, _mail->uid,
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen if (*p == '\0')
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* fallback to reading the file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen old_offset = data->stream == NULL ? 0 : data->stream->v_offset;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (mail_get_stream(_mail, &hdr_size, &body_size) == NULL)
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen /* 1 = pop3-only, 0 = mixed, -1 = no pop3 */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_VIRTUAL_FULL_SIZE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* if virtual size is wanted permanently, store it to uidlist
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen so that in case cache file gets lost we can get it quickly */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir_uidlist_set_ext(mbox->uidlist, _mail->uid,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic const char *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmaildir_mail_get_special(struct mail *_mail, enum mail_fetch_field field)
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen if (!maildir_mail_get_fname(mbox, _mail, &fname))
659fe5d24825b160cae512538088020d97a60239Timo Sirainen path = maildir_save_file_get_path(_mail->transaction,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return end == NULL ? fname : t_strdup_until(fname, end);
659fe5d24825b160cae512538088020d97a60239Timo Sirainenstatic uoff_t maildir_mail_get_physical_size(struct mail *_mail)
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen if (!maildir_mail_get_fname(mbox, _mail, &fname))
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen path = maildir_save_file_get_path(_mail->transaction,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* size can be included in filename */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!maildir_filename_get_size(fname, MAILDIR_EXTRA_FILE_SIZE, &size)) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen /* saved mail which hasn't been committed yet */
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_PHYSICAL_FULL_SIZE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic struct istream *maildir_mail_get_stream(struct mail *_mail,
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen struct index_mail *mail = (struct index_mail *)_mail;
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen data->stream = maildir_open_mail(mbox, _mail, &deleted);