Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-imap/imap-message-cache.c @ 50:d493b9cc265e HEAD
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
to be able to handle off_t overflows properly. Also changed a few unsigned
int fields into uoff_t so we should now support >2G mails if uoff_t is
64bit. Also fixed several potential integer overflows.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 27 Aug 2002 22:16:54 +0300 |
parents | a946ce1f09b7 |
children | d0a9a516f00f |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "lib.h" | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
4 #include "iobuffer.h" |
0 | 5 #include "temp-string.h" |
6 #include "mmap-util.h" | |
7 #include "message-parser.h" | |
8 #include "message-size.h" | |
9 #include "imap-bodystructure.h" | |
10 #include "imap-envelope.h" | |
11 #include "imap-message-cache.h" | |
12 | |
13 #include <unistd.h> | |
14 | |
15 /* It's not very useful to cache lots of messages, as they're mostly wanted | |
16 just once. The biggest reason for this cache to exist is to get just the | |
17 latest message. */ | |
18 #define MAX_CACHED_MESSAGES 16 | |
19 | |
20 #define DEFAULT_MESSAGE_POOL_SIZE 4096 | |
21 | |
22 typedef struct _CachedMessage CachedMessage; | |
23 | |
24 struct _CachedMessage { | |
25 CachedMessage *next; | |
26 | |
27 Pool pool; | |
28 unsigned int uid; | |
29 | |
30 MessagePart *part; | |
31 MessageSize *hdr_size; | |
32 MessageSize *body_size; | |
33 MessageSize *partial_size; | |
34 | |
35 char *cached_body; | |
36 char *cached_bodystructure; | |
37 char *cached_envelope; | |
38 | |
39 MessagePartEnvelopeData *envelope; | |
40 }; | |
41 | |
42 struct _ImapMessageCache { | |
43 CachedMessage *messages; | |
44 int messages_count; | |
45 | |
46 CachedMessage *open_msg; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
47 IOBuffer *open_inbuf; |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
48 uoff_t open_virtual_size; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
49 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
50 IOBuffer *(*inbuf_rewind)(IOBuffer *inbuf, void *context); |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
51 void *context; |
0 | 52 }; |
53 | |
54 ImapMessageCache *imap_msgcache_alloc(void) | |
55 { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
56 return i_new(ImapMessageCache, 1); |
0 | 57 } |
58 | |
59 static void cached_message_free(CachedMessage *msg) | |
60 { | |
61 pool_unref(msg->pool); | |
62 } | |
63 | |
64 void imap_msgcache_clear(ImapMessageCache *cache) | |
65 { | |
66 CachedMessage *next; | |
67 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
68 imap_msgcache_close(cache); |
0 | 69 |
70 while (cache->messages != NULL) { | |
71 next = cache->messages->next; | |
72 cached_message_free(cache->messages); | |
73 cache->messages = next; | |
74 } | |
75 } | |
76 | |
77 void imap_msgcache_free(ImapMessageCache *cache) | |
78 { | |
79 imap_msgcache_clear(cache); | |
80 i_free(cache); | |
81 } | |
82 | |
83 static CachedMessage *cache_new(ImapMessageCache *cache, unsigned int uid) | |
84 { | |
85 CachedMessage *msg, **msgp; | |
86 Pool pool; | |
87 | |
88 if (cache->messages_count < MAX_CACHED_MESSAGES) | |
89 cache->messages_count++; | |
90 else { | |
91 /* remove the last message from cache */ | |
92 msgp = &cache->messages; | |
93 while ((*msgp)->next != NULL) | |
94 msgp = &(*msgp)->next; | |
95 | |
96 cached_message_free(*msgp); | |
97 *msgp = NULL; | |
98 } | |
99 | |
100 pool = pool_create("CachedMessage", DEFAULT_MESSAGE_POOL_SIZE, FALSE); | |
101 | |
102 msg = p_new(pool, CachedMessage, 1); | |
103 msg->pool = pool; | |
104 msg->uid = uid; | |
105 | |
106 msg->next = cache->messages; | |
107 cache->messages = msg; | |
108 return msg; | |
109 } | |
110 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
111 static CachedMessage *cache_open_or_create(ImapMessageCache *cache, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
112 unsigned int uid) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
113 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
114 CachedMessage **pos, *msg; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
115 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
116 pos = &cache->messages; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
117 for (; *pos != NULL; pos = &(*pos)->next) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
118 if ((*pos)->uid == uid) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
119 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
120 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
121 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
122 if (*pos == NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
123 /* not found, add it */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
124 msg = cache_new(cache, uid); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
125 } else if (*pos != cache->messages) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
126 /* move it to first in list */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
127 msg = *pos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
128 *pos = msg->next; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
129 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
130 msg->next = cache->messages; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
131 cache->messages = msg; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
132 } else { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
133 msg = *pos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
134 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
135 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
136 return msg; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
137 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
138 |
0 | 139 static void parse_envelope_header(MessagePart *part, |
140 const char *name, unsigned int name_len, | |
141 const char *value, unsigned int value_len, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
142 void *context) |
0 | 143 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
144 CachedMessage *msg = context; |
0 | 145 |
146 if (part == NULL || part->parent == NULL) { | |
147 /* parse envelope headers if we're at the root message part */ | |
148 imap_envelope_parse_header(msg->pool, &msg->envelope, | |
149 t_strndup(name, name_len), | |
150 value, value_len); | |
151 } | |
152 } | |
153 | |
154 static CachedMessage *cache_find(ImapMessageCache *cache, unsigned int uid) | |
155 { | |
156 CachedMessage *msg; | |
157 | |
158 for (msg = cache->messages; msg != NULL; msg = msg->next) { | |
159 if (msg->uid == uid) | |
160 return msg; | |
161 } | |
162 | |
163 return NULL; | |
164 } | |
165 | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
166 static void imap_msgcache_get_inbuf(ImapMessageCache *cache, uoff_t offset) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
167 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
168 if (offset < cache->open_inbuf->offset) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
169 /* need to rewind */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
170 cache->open_inbuf = cache->inbuf_rewind(cache->open_inbuf, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
171 cache->context); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
172 if (cache->open_inbuf == NULL) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
173 i_fatal("Can't rewind message buffer"); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
174 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
175 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
176 io_buffer_skip(cache->open_inbuf, offset - cache->open_inbuf->offset); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
177 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
178 |
0 | 179 int imap_msgcache_is_cached(ImapMessageCache *cache, unsigned int uid, |
180 ImapCacheField fields) | |
181 { | |
182 CachedMessage *msg; | |
183 | |
184 if (cache->open_msg != NULL && cache->open_msg->uid == uid) | |
185 return TRUE; | |
186 | |
187 /* not open, see if the wanted fields are cached */ | |
188 msg = cache_find(cache, uid); | |
189 if (msg == NULL) | |
190 return FALSE; | |
191 | |
192 if ((fields & IMAP_CACHE_BODY) && msg->cached_body == NULL) | |
193 return FALSE; | |
194 if ((fields & IMAP_CACHE_BODYSTRUCTURE) && | |
195 msg->cached_bodystructure == NULL) | |
196 return FALSE; | |
197 if ((fields & IMAP_CACHE_ENVELOPE) && msg->cached_envelope == NULL) | |
198 return FALSE; | |
199 | |
200 if ((fields & IMAP_CACHE_MESSAGE_OPEN) && msg != cache->open_msg) | |
201 return FALSE; | |
202 if ((fields & IMAP_CACHE_MESSAGE_PART) && msg->part == NULL) | |
203 return FALSE; | |
204 if ((fields & IMAP_CACHE_MESSAGE_HDR_SIZE) && msg->hdr_size == NULL) | |
205 return FALSE; | |
206 if ((fields & IMAP_CACHE_MESSAGE_BODY_SIZE) && msg->body_size == NULL) | |
207 return FALSE; | |
208 | |
209 return TRUE; | |
210 } | |
211 | |
212 /* Caches the fields for given message if possible */ | |
213 static void cache_fields(ImapMessageCache *cache, CachedMessage *msg, | |
214 ImapCacheField fields) | |
215 { | |
216 const char *value; | |
217 | |
218 t_push(); | |
219 if ((fields & IMAP_CACHE_BODY) && msg->cached_body == NULL && | |
220 msg == cache->open_msg) { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
221 imap_msgcache_get_inbuf(cache, 0); |
0 | 222 value = imap_part_get_bodystructure(msg->pool, &msg->part, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
223 cache->open_inbuf, FALSE); |
0 | 224 msg->cached_body = p_strdup(msg->pool, value); |
225 } | |
226 | |
227 if ((fields & IMAP_CACHE_BODYSTRUCTURE) && | |
228 msg->cached_bodystructure == NULL && msg == cache->open_msg) { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
229 imap_msgcache_get_inbuf(cache, 0); |
0 | 230 value = imap_part_get_bodystructure(msg->pool, &msg->part, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
231 cache->open_inbuf, TRUE); |
0 | 232 msg->cached_bodystructure = p_strdup(msg->pool, value); |
233 } | |
234 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
235 if ((fields & IMAP_CACHE_ENVELOPE) && msg->cached_envelope == NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
236 if (msg->envelope == NULL && msg == cache->open_msg) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
237 /* envelope isn't parsed yet, do it. header size |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
238 is calculated anyway so save it */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
239 if (msg->hdr_size == NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
240 msg->hdr_size = p_new(msg->pool, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
241 MessageSize, 1); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
242 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
243 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
244 imap_msgcache_get_inbuf(cache, 0); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
245 message_parse_header(NULL, cache->open_inbuf, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
246 msg->hdr_size, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
247 parse_envelope_header, msg); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
248 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
249 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
250 if (msg->envelope != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
251 value = imap_envelope_get_part_data(msg->envelope); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
252 msg->cached_envelope = p_strdup(msg->pool, value); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
253 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
254 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
255 |
0 | 256 if ((fields & IMAP_CACHE_MESSAGE_PART) && msg->part == NULL && |
257 msg == cache->open_msg) { | |
258 /* we need to parse the message */ | |
259 MessageHeaderFunc func; | |
260 | |
261 if ((fields & IMAP_CACHE_ENVELOPE) && | |
262 msg->cached_envelope == NULL) { | |
263 /* we need envelope too, fill the info | |
264 while parsing headers */ | |
265 func = parse_envelope_header; | |
266 } else { | |
267 func = NULL; | |
268 } | |
269 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
270 imap_msgcache_get_inbuf(cache, 0); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
271 msg->part = message_parse(msg->pool, cache->open_inbuf, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
272 func, msg); |
0 | 273 } |
274 | |
275 if ((fields & IMAP_CACHE_MESSAGE_BODY_SIZE) && | |
276 msg->body_size == NULL && | |
277 (msg == cache->open_msg || msg->part != NULL)) { | |
278 /* fill the body size, and while at it fill the header size | |
279 as well */ | |
280 if (msg->hdr_size == NULL) | |
281 msg->hdr_size = p_new(msg->pool, MessageSize, 1); | |
282 msg->body_size = p_new(msg->pool, MessageSize, 1); | |
283 | |
284 if (msg->part != NULL) { | |
285 /* easy, get it from root part */ | |
286 *msg->hdr_size = msg->part->header_size; | |
287 *msg->body_size = msg->part->body_size; | |
288 } else { | |
289 /* first get the header's size, then calculate the | |
290 body size from it and the total virtual size */ | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
291 imap_msgcache_get_inbuf(cache, 0); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
292 message_get_header_size(cache->open_inbuf, |
0 | 293 msg->hdr_size); |
294 | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
295 /* FIXME: this may actually happen if file size is |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
296 shrinked.. */ |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
297 i_assert(msg->hdr_size->physical_size < |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
298 cache->open_inbuf->size); |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
299 i_assert(msg->hdr_size->virtual_size < |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
300 cache->open_virtual_size); |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
301 |
0 | 302 msg->body_size->lines = 0; |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
303 msg->body_size->physical_size = |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
304 cache->open_inbuf->size - |
0 | 305 msg->hdr_size->physical_size; |
306 msg->body_size->virtual_size = | |
307 cache->open_virtual_size - | |
308 msg->hdr_size->virtual_size; | |
309 } | |
310 } | |
311 | |
312 if ((fields & IMAP_CACHE_MESSAGE_HDR_SIZE) && msg->hdr_size == NULL && | |
313 (msg == cache->open_msg || msg->part != NULL)) { | |
314 msg->hdr_size = p_new(msg->pool, MessageSize, 1); | |
315 | |
316 if (msg->part != NULL) { | |
317 /* easy, get it from root part */ | |
318 *msg->hdr_size = msg->part->header_size; | |
319 } else { | |
320 /* need to do some light parsing */ | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
321 imap_msgcache_get_inbuf(cache, 0); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
322 message_get_header_size(cache->open_inbuf, |
0 | 323 msg->hdr_size); |
324 } | |
325 } | |
326 | |
327 t_pop(); | |
328 } | |
329 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
330 void imap_msgcache_message(ImapMessageCache *cache, unsigned int uid, |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
331 ImapCacheField fields, uoff_t virtual_size, |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
332 uoff_t pv_headers_size, uoff_t pv_body_size, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
333 IOBuffer *inbuf, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
334 IOBuffer *(*inbuf_rewind)(IOBuffer *inbuf, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
335 void *context), |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
336 void *context) |
0 | 337 { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
338 CachedMessage *msg; |
0 | 339 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
340 msg = cache_open_or_create(cache, uid); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
341 if (cache->open_msg != msg) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
342 imap_msgcache_close(cache); |
0 | 343 |
344 cache->open_msg = msg; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
345 cache->open_inbuf = inbuf; |
0 | 346 cache->open_virtual_size = virtual_size; |
347 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
348 cache->inbuf_rewind = inbuf_rewind; |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
349 cache->context = context; |
0 | 350 } |
351 | |
352 if (pv_headers_size != 0 && msg->hdr_size == NULL) { | |
353 /* physical size == virtual size */ | |
354 msg->hdr_size = p_new(msg->pool, MessageSize, 1); | |
355 msg->hdr_size->physical_size = msg->hdr_size->virtual_size = | |
356 pv_headers_size; | |
357 } | |
358 | |
359 if (pv_body_size != 0 && msg->body_size == NULL) { | |
360 /* physical size == virtual size */ | |
361 msg->body_size = p_new(msg->pool, MessageSize, 1); | |
362 msg->body_size->physical_size = msg->body_size->virtual_size = | |
363 pv_body_size; | |
364 } | |
365 | |
366 cache_fields(cache, msg, fields); | |
367 } | |
368 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
369 void imap_msgcache_close(ImapMessageCache *cache) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
370 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
371 if (cache->open_inbuf != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
372 (void)close(cache->open_inbuf->fd); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
373 io_buffer_destroy(cache->open_inbuf); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
374 cache->open_inbuf = NULL; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
375 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
376 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
377 cache->open_msg = NULL; |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
378 cache->open_virtual_size = 0; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
379 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
380 |
0 | 381 void imap_msgcache_set(ImapMessageCache *cache, unsigned int uid, |
382 ImapCacheField field, const char *value) | |
383 { | |
384 CachedMessage *msg; | |
385 | |
386 msg = cache_find(cache, uid); | |
387 if (msg == NULL) | |
388 msg = cache_new(cache, uid); | |
389 | |
390 switch (field) { | |
391 case IMAP_CACHE_BODY: | |
392 msg->cached_body = p_strdup(msg->pool, value); | |
393 break; | |
394 case IMAP_CACHE_BODYSTRUCTURE: | |
395 msg->cached_bodystructure = p_strdup(msg->pool, value); | |
396 break; | |
397 case IMAP_CACHE_ENVELOPE: | |
398 msg->cached_envelope = p_strdup(msg->pool, value); | |
399 break; | |
400 default: | |
401 i_assert(0); | |
402 } | |
403 } | |
404 | |
405 const char *imap_msgcache_get(ImapMessageCache *cache, unsigned int uid, | |
406 ImapCacheField field) | |
407 { | |
408 CachedMessage *msg; | |
409 | |
410 msg = cache_find(cache, uid); | |
411 if (msg == NULL) | |
412 return NULL; | |
413 | |
414 switch (field) { | |
415 case IMAP_CACHE_BODY: | |
416 if (msg->cached_body == NULL) | |
417 cache_fields(cache, msg, field); | |
418 return msg->cached_body; | |
419 case IMAP_CACHE_BODYSTRUCTURE: | |
420 if (msg->cached_bodystructure == NULL) | |
421 cache_fields(cache, msg, field); | |
422 return msg->cached_bodystructure; | |
423 case IMAP_CACHE_ENVELOPE: | |
424 if (msg->cached_envelope == NULL) | |
425 cache_fields(cache, msg, field); | |
426 return msg->cached_envelope; | |
427 default: | |
428 i_assert(0); | |
429 } | |
430 | |
431 return NULL; | |
432 } | |
433 | |
434 MessagePart *imap_msgcache_get_parts(ImapMessageCache *cache, unsigned int uid) | |
435 { | |
436 CachedMessage *msg; | |
437 | |
438 msg = cache_find(cache, uid); | |
439 if (msg == NULL) | |
440 return NULL; | |
441 | |
442 if (msg->part == NULL) | |
443 cache_fields(cache, msg, IMAP_CACHE_MESSAGE_PART); | |
444 return msg->part; | |
445 } | |
446 | |
447 int imap_msgcache_get_rfc822(ImapMessageCache *cache, unsigned int uid, | |
448 MessageSize *hdr_size, MessageSize *body_size, | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
449 IOBuffer **inbuf) |
0 | 450 { |
451 CachedMessage *msg; | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
452 uoff_t offset; |
0 | 453 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
454 if (inbuf != NULL) { |
0 | 455 if (cache->open_msg == NULL || cache->open_msg->uid != uid) |
456 return FALSE; | |
457 | |
458 msg = cache->open_msg; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
459 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
460 offset = hdr_size != NULL ? 0 : |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
461 msg->hdr_size->physical_size; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
462 imap_msgcache_get_inbuf(cache, offset); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
463 *inbuf = cache->open_inbuf; |
0 | 464 } else { |
465 msg = cache_find(cache, uid); | |
466 if (msg == NULL) | |
467 return FALSE; | |
468 } | |
469 | |
470 if (body_size != NULL) { | |
471 if (msg->body_size == NULL) | |
472 cache_fields(cache, msg, IMAP_CACHE_MESSAGE_BODY_SIZE); | |
473 if (msg->body_size == NULL) | |
474 return FALSE; | |
475 *body_size = *msg->body_size; | |
476 } | |
477 | |
478 if (hdr_size != NULL) { | |
479 if (msg->hdr_size == NULL) | |
480 cache_fields(cache, msg, IMAP_CACHE_MESSAGE_HDR_SIZE); | |
481 if (msg->hdr_size == NULL) | |
482 return FALSE; | |
483 *hdr_size = *msg->hdr_size; | |
484 } | |
485 | |
486 return TRUE; | |
487 } | |
488 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
489 static void get_partial_size(IOBuffer *inbuf, |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
490 uoff_t virtual_skip, uoff_t max_virtual_size, |
0 | 491 MessageSize *partial, MessageSize *dest) |
492 { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
493 unsigned char *msg; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
494 unsigned int size; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
495 int cr_skipped; |
0 | 496 |
497 /* see if we can use the existing partial */ | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
498 if (partial->virtual_size > virtual_skip) |
0 | 499 memset(partial, 0, sizeof(MessageSize)); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
500 else { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
501 io_buffer_skip(inbuf, partial->physical_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
502 virtual_skip -= partial->virtual_size; |
0 | 503 } |
504 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
505 message_skip_virtual(inbuf, virtual_skip, partial, &cr_skipped); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
506 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
507 if (!cr_skipped) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
508 /* see if we need to add virtual CR */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
509 while (io_buffer_read_data(inbuf, &msg, &size, 0) >= 0) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
510 if (size > 0) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
511 if (msg[0] == '\n') |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
512 dest->virtual_size++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
513 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
514 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
515 } |
0 | 516 } |
517 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
518 message_get_body_size(inbuf, dest, max_virtual_size); |
0 | 519 } |
520 | |
521 int imap_msgcache_get_rfc822_partial(ImapMessageCache *cache, unsigned int uid, | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
522 uoff_t virtual_skip, |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
523 uoff_t max_virtual_size, |
0 | 524 int get_header, MessageSize *size, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
525 IOBuffer **inbuf) |
0 | 526 { |
527 CachedMessage *msg; | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
528 uoff_t physical_skip; |
0 | 529 int size_got; |
530 | |
531 msg = cache->open_msg; | |
532 if (msg == NULL || msg->uid != uid) | |
533 return FALSE; | |
534 | |
535 if (msg->hdr_size == NULL) { | |
536 msg->hdr_size = p_new(msg->pool, MessageSize, 1); | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
537 imap_msgcache_get_inbuf(cache, 0); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
538 message_get_header_size(cache->open_inbuf, msg->hdr_size); |
0 | 539 } |
540 | |
541 physical_skip = get_header ? 0 : msg->hdr_size->physical_size; | |
542 | |
543 /* see if we can do this easily */ | |
544 size_got = FALSE; | |
545 if (virtual_skip == 0) { | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
546 if (msg->body_size == NULL) { |
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
547 /* FIXME: may underflow */ |
0 | 548 msg->body_size = p_new(msg->pool, MessageSize, 1); |
22
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
549 msg->body_size->physical_size = |
a946ce1f09b7
mbox fixes, not fully working yet but almost :)
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
550 cache->open_inbuf->size - |
0 | 551 msg->hdr_size->physical_size; |
552 msg->body_size->virtual_size = | |
553 cache->open_virtual_size - | |
554 msg->hdr_size->virtual_size; | |
555 } | |
556 | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
22
diff
changeset
|
557 if (max_virtual_size >= msg->body_size->virtual_size) { |
0 | 558 *size = *msg->body_size; |
559 size_got = TRUE; | |
560 } | |
561 } | |
562 | |
563 if (!size_got) { | |
564 if (msg->partial_size == NULL) | |
565 msg->partial_size = p_new(msg->pool, MessageSize, 1); | |
566 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
567 imap_msgcache_get_inbuf(cache, msg->hdr_size->physical_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
568 get_partial_size(cache->open_inbuf, virtual_skip, |
0 | 569 max_virtual_size, msg->partial_size, size); |
570 | |
571 physical_skip += msg->partial_size->physical_size; | |
572 } | |
573 | |
574 if (get_header) | |
575 message_size_add(size, msg->hdr_size); | |
576 | |
577 /* seek to wanted position */ | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
578 imap_msgcache_get_inbuf(cache, physical_skip); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
579 *inbuf = cache->open_inbuf; |
0 | 580 return TRUE; |
581 } | |
582 | |
583 int imap_msgcache_get_data(ImapMessageCache *cache, unsigned int uid, | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
584 IOBuffer **inbuf) |
0 | 585 { |
586 if (cache->open_msg == NULL || cache->open_msg->uid != uid) | |
587 return FALSE; | |
588 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
589 imap_msgcache_get_inbuf(cache, 0); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
590 *inbuf = cache->open_inbuf; |
0 | 591 return TRUE; |
592 } |