Diffstat (limited to 'kmicromail/libetpan/generic/mboxdriver_tools.c') (more/less context) (show whitespace changes)
-rw-r--r-- | kmicromail/libetpan/generic/mboxdriver_tools.c | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/kmicromail/libetpan/generic/mboxdriver_tools.c b/kmicromail/libetpan/generic/mboxdriver_tools.c new file mode 100644 index 0000000..1e27798 --- a/dev/null +++ b/kmicromail/libetpan/generic/mboxdriver_tools.c | |||
@@ -0,0 +1,434 @@ | |||
1 | /* | ||
2 | * libEtPan! -- a mail stuff library | ||
3 | * | ||
4 | * Copyright (C) 2001, 2002 - DINH Viet Hoa | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions | ||
9 | * are met: | ||
10 | * 1. Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * 2. Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the distribution. | ||
15 | * 3. Neither the name of the libEtPan! project nor the names of its | ||
16 | * contributors may be used to endorse or promote products derived | ||
17 | * from this software without specific prior written permission. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
29 | * SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | /* | ||
33 | * $Id$ | ||
34 | */ | ||
35 | |||
36 | #include "mboxdriver_tools.h" | ||
37 | |||
38 | #include <sys/types.h> | ||
39 | #include <sys/stat.h> | ||
40 | #include <fcntl.h> | ||
41 | #include <unistd.h> | ||
42 | |||
43 | #include "maildriver_types.h" | ||
44 | #include "mailmbox.h" | ||
45 | #include "mboxdriver_cached.h" | ||
46 | #include "mboxdriver.h" | ||
47 | #include "generic_cache.h" | ||
48 | #include "mailmessage.h" | ||
49 | #include "imfcache.h" | ||
50 | #include "mail_cache_db.h" | ||
51 | |||
52 | static inline struct mbox_session_state_data * | ||
53 | session_get_data(mailsession * session) | ||
54 | { | ||
55 | return session->sess_data; | ||
56 | } | ||
57 | |||
58 | static inline struct mailmbox_folder * | ||
59 | session_get_mbox_session(mailsession * session) | ||
60 | { | ||
61 | return session_get_data(session)->mbox_folder; | ||
62 | } | ||
63 | |||
64 | static inline struct mbox_cached_session_state_data * | ||
65 | cached_session_get_data(mailsession * session) | ||
66 | { | ||
67 | return session->sess_data; | ||
68 | } | ||
69 | |||
70 | static inline mailsession * | ||
71 | cached_session_get_ancestor(mailsession * session) | ||
72 | { | ||
73 | return cached_session_get_data(session)->mbox_ancestor; | ||
74 | } | ||
75 | |||
76 | static inline struct mbox_session_state_data * | ||
77 | cached_session_get_ancestor_data(mailsession * session) | ||
78 | { | ||
79 | return cached_session_get_ancestor(session)->sess_data; | ||
80 | } | ||
81 | |||
82 | static inline struct mailmbox_folder * | ||
83 | cached_session_get_mbox_session(mailsession * session) | ||
84 | { | ||
85 | return session_get_mbox_session(cached_session_get_ancestor(session)); | ||
86 | } | ||
87 | |||
88 | |||
89 | int mboxdriver_mbox_error_to_mail_error(int error) | ||
90 | { | ||
91 | switch (error) { | ||
92 | case MAILMBOX_NO_ERROR: | ||
93 | return MAIL_NO_ERROR; | ||
94 | |||
95 | case MAILMBOX_ERROR_PARSE: | ||
96 | return MAIL_ERROR_PARSE; | ||
97 | |||
98 | case MAILMBOX_ERROR_INVAL: | ||
99 | return MAIL_ERROR_INVAL; | ||
100 | |||
101 | case MAILMBOX_ERROR_FILE_NOT_FOUND: | ||
102 | return MAIL_ERROR_PARSE; | ||
103 | |||
104 | case MAILMBOX_ERROR_MEMORY: | ||
105 | return MAIL_ERROR_MEMORY; | ||
106 | |||
107 | case MAILMBOX_ERROR_TEMPORARY_FILE: | ||
108 | return MAIL_ERROR_PARSE; | ||
109 | |||
110 | case MAILMBOX_ERROR_FILE: | ||
111 | return MAIL_ERROR_FILE; | ||
112 | |||
113 | case MAILMBOX_ERROR_MSG_NOT_FOUND: | ||
114 | return MAIL_ERROR_MSG_NOT_FOUND; | ||
115 | |||
116 | case MAILMBOX_ERROR_READONLY: | ||
117 | return MAIL_ERROR_READONLY; | ||
118 | |||
119 | default: | ||
120 | return MAIL_ERROR_INVAL; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | int mboxdriver_fetch_msg(mailsession * session, uint32_t index, | ||
125 | char ** result, size_t * result_len) | ||
126 | { | ||
127 | int r; | ||
128 | char * msg_content; | ||
129 | size_t msg_length; | ||
130 | struct mailmbox_folder * folder; | ||
131 | |||
132 | folder = session_get_mbox_session(session); | ||
133 | if (folder == NULL) | ||
134 | return MAIL_ERROR_BAD_STATE; | ||
135 | |||
136 | r = mailmbox_fetch_msg(folder, index, &msg_content, &msg_length); | ||
137 | if (r != MAILMBOX_NO_ERROR) | ||
138 | return mboxdriver_mbox_error_to_mail_error(r); | ||
139 | |||
140 | * result = msg_content; | ||
141 | * result_len = msg_length; | ||
142 | |||
143 | return MAIL_NO_ERROR; | ||
144 | } | ||
145 | |||
146 | |||
147 | int mboxdriver_fetch_size(mailsession * session, uint32_t index, | ||
148 | size_t * result) | ||
149 | { | ||
150 | struct mailmbox_folder * folder; | ||
151 | int r; | ||
152 | char * data; | ||
153 | size_t len; | ||
154 | int res; | ||
155 | |||
156 | folder = session_get_mbox_session(session); | ||
157 | if (folder == NULL) { | ||
158 | res = MAIL_ERROR_FETCH; | ||
159 | goto err; | ||
160 | } | ||
161 | |||
162 | r = mailmbox_validate_read_lock(folder); | ||
163 | if (r != MAILMBOX_NO_ERROR) { | ||
164 | res = mboxdriver_mbox_error_to_mail_error(r); | ||
165 | goto err; | ||
166 | } | ||
167 | |||
168 | r = mailmbox_fetch_msg_no_lock(folder, index, &data, &len); | ||
169 | if (r != MAILMBOX_NO_ERROR) { | ||
170 | res = mboxdriver_mbox_error_to_mail_error(r); | ||
171 | goto unlock; | ||
172 | } | ||
173 | |||
174 | mailmbox_read_unlock(folder); | ||
175 | |||
176 | * result = len; | ||
177 | |||
178 | return MAIL_NO_ERROR; | ||
179 | |||
180 | unlock: | ||
181 | mailmbox_read_unlock(folder); | ||
182 | err: | ||
183 | return res; | ||
184 | } | ||
185 | |||
186 | |||
187 | int | ||
188 | mboxdriver_get_cached_flags(struct mail_cache_db * cache_db, | ||
189 | MMAPString * mmapstr, | ||
190 | mailsession * session, | ||
191 | uint32_t num, | ||
192 | struct mail_flags ** result) | ||
193 | { | ||
194 | int r; | ||
195 | char keyname[PATH_MAX]; | ||
196 | struct mail_flags * flags; | ||
197 | int res; | ||
198 | struct mailmbox_msg_info * info; | ||
199 | struct mailmbox_folder * folder; | ||
200 | chashdatum key; | ||
201 | chashdatum data; | ||
202 | |||
203 | folder = cached_session_get_mbox_session(session); | ||
204 | if (folder == NULL) { | ||
205 | res = MAIL_ERROR_BAD_STATE; | ||
206 | goto err; | ||
207 | } | ||
208 | |||
209 | key.data = # | ||
210 | key.len = sizeof(num); | ||
211 | |||
212 | r = chash_get(folder->mb_hash, &key, &data); | ||
213 | if (r < 0) { | ||
214 | res = MAIL_ERROR_MSG_NOT_FOUND; | ||
215 | goto err; | ||
216 | } | ||
217 | |||
218 | info = data.data; | ||
219 | |||
220 | snprintf(keyname, PATH_MAX, "%u-%u-flags", num, info->msg_body_len); | ||
221 | |||
222 | r = generic_cache_flags_read(cache_db, mmapstr, keyname, &flags); | ||
223 | if (r != MAIL_NO_ERROR) { | ||
224 | res = r; | ||
225 | goto err; | ||
226 | } | ||
227 | |||
228 | * result = flags; | ||
229 | |||
230 | return MAIL_NO_ERROR; | ||
231 | |||
232 | err: | ||
233 | return res; | ||
234 | } | ||
235 | |||
236 | int | ||
237 | mboxdriver_write_cached_flags(struct mail_cache_db * cache_db, | ||
238 | MMAPString * mmapstr, | ||
239 | char * uid, | ||
240 | struct mail_flags * flags) | ||
241 | { | ||
242 | int r; | ||
243 | char keyname[PATH_MAX]; | ||
244 | int res; | ||
245 | |||
246 | snprintf(keyname, PATH_MAX, "%s-flags", uid); | ||
247 | |||
248 | r = generic_cache_flags_write(cache_db, mmapstr, keyname, flags); | ||
249 | if (r != MAIL_NO_ERROR) { | ||
250 | res = r; | ||
251 | goto err; | ||
252 | } | ||
253 | |||
254 | return MAIL_NO_ERROR; | ||
255 | |||
256 | err: | ||
257 | return res; | ||
258 | } | ||
259 | |||
260 | |||
261 | int mboxdriver_fetch_header(mailsession * session, uint32_t index, | ||
262 | char ** result, size_t * result_len) | ||
263 | { | ||
264 | int r; | ||
265 | char * msg_content; | ||
266 | size_t msg_length; | ||
267 | struct mailmbox_folder * folder; | ||
268 | |||
269 | folder = session_get_mbox_session(session); | ||
270 | if (folder == NULL) | ||
271 | return MAIL_ERROR_BAD_STATE; | ||
272 | |||
273 | r = mailmbox_fetch_msg_headers(folder, index, &msg_content, &msg_length); | ||
274 | if (r != MAILMBOX_NO_ERROR) | ||
275 | return mboxdriver_mbox_error_to_mail_error(r); | ||
276 | |||
277 | * result = msg_content; | ||
278 | * result_len = msg_length; | ||
279 | |||
280 | return MAIL_NO_ERROR; | ||
281 | } | ||
282 | |||
283 | int mbox_get_locked_messages_list(struct mailmbox_folder * folder, | ||
284 | mailsession * session, | ||
285 | mailmessage_driver * driver, | ||
286 | int (* lock)(struct mailmbox_folder *), | ||
287 | int (* unlock)(struct mailmbox_folder *), | ||
288 | struct mailmessage_list ** result) | ||
289 | { | ||
290 | struct mailmessage_list * env_list; | ||
291 | unsigned int i; | ||
292 | int r; | ||
293 | int res; | ||
294 | carray * tab; | ||
295 | |||
296 | tab = carray_new(128); | ||
297 | if (tab == NULL) { | ||
298 | res = MAIL_ERROR_MEMORY; | ||
299 | goto err; | ||
300 | } | ||
301 | |||
302 | r = lock(folder); | ||
303 | if (r != MAIL_NO_ERROR) { | ||
304 | res = r; | ||
305 | goto free; | ||
306 | } | ||
307 | |||
308 | for(i = 0 ; i < carray_count(folder->mb_tab) ; i ++) { | ||
309 | struct mailmbox_msg_info * msg_info; | ||
310 | mailmessage * msg; | ||
311 | |||
312 | msg_info = carray_get(folder->mb_tab, i); | ||
313 | if (msg_info == NULL) | ||
314 | continue; | ||
315 | |||
316 | if (msg_info->msg_deleted) | ||
317 | continue; | ||
318 | |||
319 | msg = mailmessage_new(); | ||
320 | if (msg == NULL) { | ||
321 | res = MAIL_ERROR_MEMORY; | ||
322 | goto unlock; | ||
323 | } | ||
324 | |||
325 | r = mailmessage_init(msg, session, driver, msg_info->msg_uid, | ||
326 | msg_info->msg_size - msg_info->msg_start_len); | ||
327 | if (r != MAIL_NO_ERROR) { | ||
328 | res = r; | ||
329 | goto unlock; | ||
330 | } | ||
331 | |||
332 | r = carray_add(tab, msg, NULL); | ||
333 | if (r < 0) { | ||
334 | mailmessage_free(msg); | ||
335 | res = MAIL_ERROR_MEMORY; | ||
336 | goto unlock; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | env_list = mailmessage_list_new(tab); | ||
341 | if (env_list == NULL) { | ||
342 | res = MAIL_ERROR_MEMORY; | ||
343 | goto unlock; | ||
344 | } | ||
345 | |||
346 | unlock(folder); | ||
347 | |||
348 | * result = env_list; | ||
349 | |||
350 | return MAIL_NO_ERROR; | ||
351 | |||
352 | unlock: | ||
353 | unlock(folder); | ||
354 | free: | ||
355 | for(i = 0 ; i < carray_count(tab) ; i ++) | ||
356 | mailmessage_free(carray_get(tab, i)); | ||
357 | carray_free(tab); | ||
358 | err: | ||
359 | return res; | ||
360 | } | ||
361 | |||
362 | static int release_read_mbox(struct mailmbox_folder * folder) | ||
363 | { | ||
364 | int r; | ||
365 | |||
366 | r = mailmbox_read_unlock(folder); | ||
367 | return mboxdriver_mbox_error_to_mail_error(r); | ||
368 | } | ||
369 | |||
370 | static int acquire_read_mbox(struct mailmbox_folder * folder) | ||
371 | { | ||
372 | int r; | ||
373 | |||
374 | r = mailmbox_validate_read_lock(folder); | ||
375 | return mboxdriver_mbox_error_to_mail_error(r); | ||
376 | } | ||
377 | |||
378 | static int release_write_mbox(struct mailmbox_folder * folder) | ||
379 | { | ||
380 | int r; | ||
381 | |||
382 | r = mailmbox_write_unlock(folder); | ||
383 | return mboxdriver_mbox_error_to_mail_error(r); | ||
384 | } | ||
385 | |||
386 | static int acquire_write_mbox(struct mailmbox_folder * folder) | ||
387 | { | ||
388 | int r; | ||
389 | int res; | ||
390 | |||
391 | r = mailmbox_validate_write_lock(folder); | ||
392 | if (r != MAILMBOX_NO_ERROR) { | ||
393 | res = mboxdriver_mbox_error_to_mail_error(r); | ||
394 | goto err; | ||
395 | } | ||
396 | |||
397 | if (folder->mb_written_uid < folder->mb_max_uid) { | ||
398 | r = mailmbox_expunge_no_lock(folder); | ||
399 | if (r != MAILMBOX_NO_ERROR) { | ||
400 | res = mboxdriver_mbox_error_to_mail_error(r); | ||
401 | goto unlock; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | return MAIL_NO_ERROR; | ||
406 | |||
407 | unlock: | ||
408 | mailmbox_write_unlock(folder); | ||
409 | err: | ||
410 | return res; | ||
411 | } | ||
412 | |||
413 | /* get message list with all valid written UID */ | ||
414 | |||
415 | int mbox_get_uid_messages_list(struct mailmbox_folder * folder, | ||
416 | mailsession * session, | ||
417 | mailmessage_driver * driver, | ||
418 | struct mailmessage_list ** result) | ||
419 | { | ||
420 | return mbox_get_locked_messages_list(folder, session, driver, | ||
421 | acquire_write_mbox, release_write_mbox, result); | ||
422 | } | ||
423 | |||
424 | |||
425 | /* get message list */ | ||
426 | |||
427 | int mbox_get_messages_list(struct mailmbox_folder * folder, | ||
428 | mailsession * session, | ||
429 | mailmessage_driver * driver, | ||
430 | struct mailmessage_list ** result) | ||
431 | { | ||
432 | return mbox_get_locked_messages_list(folder, session, driver, | ||
433 | acquire_read_mbox, release_read_mbox, result); | ||
434 | } | ||