Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-imap/imap-message-cache.c @ 10:82b7de533f98 HEAD
s/user_data/context/ and some s/Data/Context/
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 22 Aug 2002 15:48:38 +0300 |
parents | 1b34ec11fff8 |
children | a946ce1f09b7 |
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; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
48 size_t open_size, open_virtual_size; |
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 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
166 static void imap_msgcache_get_inbuf(ImapMessageCache *cache, off_t offset) |
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 | |
295 msg->body_size->lines = 0; | |
296 msg->body_size->physical_size = cache->open_size - | |
297 msg->hdr_size->physical_size; | |
298 msg->body_size->virtual_size = | |
299 cache->open_virtual_size - | |
300 msg->hdr_size->virtual_size; | |
301 } | |
302 } | |
303 | |
304 if ((fields & IMAP_CACHE_MESSAGE_HDR_SIZE) && msg->hdr_size == NULL && | |
305 (msg == cache->open_msg || msg->part != NULL)) { | |
306 msg->hdr_size = p_new(msg->pool, MessageSize, 1); | |
307 | |
308 if (msg->part != NULL) { | |
309 /* easy, get it from root part */ | |
310 *msg->hdr_size = msg->part->header_size; | |
311 } else { | |
312 /* 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
|
313 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
|
314 message_get_header_size(cache->open_inbuf, |
0 | 315 msg->hdr_size); |
316 } | |
317 } | |
318 | |
319 t_pop(); | |
320 } | |
321 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
322 void imap_msgcache_message(ImapMessageCache *cache, 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
|
323 ImapCacheField fields, size_t virtual_size, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
324 size_t pv_headers_size, size_t pv_body_size, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
325 IOBuffer *inbuf, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
326 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
|
327 void *context), |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
5
diff
changeset
|
328 void *context) |
0 | 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 CachedMessage *msg; |
0 | 331 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
332 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
|
333 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
|
334 imap_msgcache_close(cache); |
0 | 335 |
336 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
|
337 cache->open_inbuf = inbuf; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
338 cache->open_size = cache->open_inbuf->stop_offset - |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
339 cache->open_inbuf->offset; |
0 | 340 cache->open_virtual_size = virtual_size; |
341 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
342 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
|
343 cache->context = context; |
0 | 344 } |
345 | |
346 if (pv_headers_size != 0 && msg->hdr_size == NULL) { | |
347 /* physical size == virtual size */ | |
348 msg->hdr_size = p_new(msg->pool, MessageSize, 1); | |
349 msg->hdr_size->physical_size = msg->hdr_size->virtual_size = | |
350 pv_headers_size; | |
351 } | |
352 | |
353 if (pv_body_size != 0 && msg->body_size == NULL) { | |
354 /* physical size == virtual size */ | |
355 msg->body_size = p_new(msg->pool, MessageSize, 1); | |
356 msg->body_size->physical_size = msg->body_size->virtual_size = | |
357 pv_body_size; | |
358 } | |
359 | |
360 cache_fields(cache, msg, fields); | |
361 } | |
362 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
363 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
|
364 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
365 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
|
366 (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
|
367 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
|
368 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
|
369 } |
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 cache->open_msg = NULL; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
372 cache->open_size = cache->open_virtual_size = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
373 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
374 |
0 | 375 void imap_msgcache_set(ImapMessageCache *cache, unsigned int uid, |
376 ImapCacheField field, const char *value) | |
377 { | |
378 CachedMessage *msg; | |
379 | |
380 msg = cache_find(cache, uid); | |
381 if (msg == NULL) | |
382 msg = cache_new(cache, uid); | |
383 | |
384 switch (field) { | |
385 case IMAP_CACHE_BODY: | |
386 msg->cached_body = p_strdup(msg->pool, value); | |
387 break; | |
388 case IMAP_CACHE_BODYSTRUCTURE: | |
389 msg->cached_bodystructure = p_strdup(msg->pool, value); | |
390 break; | |
391 case IMAP_CACHE_ENVELOPE: | |
392 msg->cached_envelope = p_strdup(msg->pool, value); | |
393 break; | |
394 default: | |
395 i_assert(0); | |
396 } | |
397 } | |
398 | |
399 const char *imap_msgcache_get(ImapMessageCache *cache, unsigned int uid, | |
400 ImapCacheField field) | |
401 { | |
402 CachedMessage *msg; | |
403 | |
404 msg = cache_find(cache, uid); | |
405 if (msg == NULL) | |
406 return NULL; | |
407 | |
408 switch (field) { | |
409 case IMAP_CACHE_BODY: | |
410 if (msg->cached_body == NULL) | |
411 cache_fields(cache, msg, field); | |
412 return msg->cached_body; | |
413 case IMAP_CACHE_BODYSTRUCTURE: | |
414 if (msg->cached_bodystructure == NULL) | |
415 cache_fields(cache, msg, field); | |
416 return msg->cached_bodystructure; | |
417 case IMAP_CACHE_ENVELOPE: | |
418 if (msg->cached_envelope == NULL) | |
419 cache_fields(cache, msg, field); | |
420 return msg->cached_envelope; | |
421 default: | |
422 i_assert(0); | |
423 } | |
424 | |
425 return NULL; | |
426 } | |
427 | |
428 MessagePart *imap_msgcache_get_parts(ImapMessageCache *cache, unsigned int uid) | |
429 { | |
430 CachedMessage *msg; | |
431 | |
432 msg = cache_find(cache, uid); | |
433 if (msg == NULL) | |
434 return NULL; | |
435 | |
436 if (msg->part == NULL) | |
437 cache_fields(cache, msg, IMAP_CACHE_MESSAGE_PART); | |
438 return msg->part; | |
439 } | |
440 | |
441 int imap_msgcache_get_rfc822(ImapMessageCache *cache, unsigned int uid, | |
442 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
|
443 IOBuffer **inbuf) |
0 | 444 { |
445 CachedMessage *msg; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
446 off_t offset; |
0 | 447 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
448 if (inbuf != NULL) { |
0 | 449 if (cache->open_msg == NULL || cache->open_msg->uid != uid) |
450 return FALSE; | |
451 | |
452 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
|
453 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
454 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
|
455 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
|
456 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
|
457 *inbuf = cache->open_inbuf; |
0 | 458 } else { |
459 msg = cache_find(cache, uid); | |
460 if (msg == NULL) | |
461 return FALSE; | |
462 } | |
463 | |
464 if (body_size != NULL) { | |
465 if (msg->body_size == NULL) | |
466 cache_fields(cache, msg, IMAP_CACHE_MESSAGE_BODY_SIZE); | |
467 if (msg->body_size == NULL) | |
468 return FALSE; | |
469 *body_size = *msg->body_size; | |
470 } | |
471 | |
472 if (hdr_size != NULL) { | |
473 if (msg->hdr_size == NULL) | |
474 cache_fields(cache, msg, IMAP_CACHE_MESSAGE_HDR_SIZE); | |
475 if (msg->hdr_size == NULL) | |
476 return FALSE; | |
477 *hdr_size = *msg->hdr_size; | |
478 } | |
479 | |
480 return TRUE; | |
481 } | |
482 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
483 static void get_partial_size(IOBuffer *inbuf, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
484 off_t virtual_skip, off_t max_virtual_size, |
0 | 485 MessageSize *partial, MessageSize *dest) |
486 { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
487 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
|
488 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
|
489 int cr_skipped; |
0 | 490 |
491 /* see if we can use the existing partial */ | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
492 if ((off_t)partial->virtual_size > virtual_skip) |
0 | 493 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
|
494 else { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
495 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
|
496 virtual_skip -= partial->virtual_size; |
0 | 497 } |
498 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
499 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
|
500 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
501 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
|
502 /* 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
|
503 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
|
504 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
|
505 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
|
506 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
|
507 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
508 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
509 } |
0 | 510 } |
511 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
512 message_get_body_size(inbuf, dest, max_virtual_size); |
0 | 513 } |
514 | |
515 int imap_msgcache_get_rfc822_partial(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
|
516 off_t virtual_skip, off_t max_virtual_size, |
0 | 517 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
|
518 IOBuffer **inbuf) |
0 | 519 { |
520 CachedMessage *msg; | |
521 off_t physical_skip; | |
522 int size_got; | |
523 | |
524 msg = cache->open_msg; | |
525 if (msg == NULL || msg->uid != uid) | |
526 return FALSE; | |
527 | |
528 if (msg->hdr_size == NULL) { | |
529 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
|
530 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
|
531 message_get_header_size(cache->open_inbuf, msg->hdr_size); |
0 | 532 } |
533 | |
534 physical_skip = get_header ? 0 : msg->hdr_size->physical_size; | |
535 | |
536 /* see if we can do this easily */ | |
537 size_got = FALSE; | |
538 if (virtual_skip == 0) { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
539 if (max_virtual_size < 0 && msg->body_size == NULL) { |
0 | 540 msg->body_size = p_new(msg->pool, MessageSize, 1); |
541 msg->body_size->physical_size = cache->open_size - | |
542 msg->hdr_size->physical_size; | |
543 msg->body_size->virtual_size = | |
544 cache->open_virtual_size - | |
545 msg->hdr_size->virtual_size; | |
546 } | |
547 | |
548 if (msg->body_size != NULL && | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
549 (max_virtual_size < 0 || |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
550 max_virtual_size >= (off_t)msg->body_size->virtual_size)) { |
0 | 551 *size = *msg->body_size; |
552 size_got = TRUE; | |
553 } | |
554 } | |
555 | |
556 if (!size_got) { | |
557 if (msg->partial_size == NULL) | |
558 msg->partial_size = p_new(msg->pool, MessageSize, 1); | |
559 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
560 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
|
561 get_partial_size(cache->open_inbuf, virtual_skip, |
0 | 562 max_virtual_size, msg->partial_size, size); |
563 | |
564 physical_skip += msg->partial_size->physical_size; | |
565 } | |
566 | |
567 if (get_header) | |
568 message_size_add(size, msg->hdr_size); | |
569 | |
570 /* 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
|
571 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
|
572 *inbuf = cache->open_inbuf; |
0 | 573 return TRUE; |
574 } | |
575 | |
576 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
|
577 IOBuffer **inbuf) |
0 | 578 { |
579 if (cache->open_msg == NULL || cache->open_msg->uid != uid) | |
580 return FALSE; | |
581 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
582 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
|
583 *inbuf = cache->open_inbuf; |
0 | 584 return TRUE; |
585 } |